From 7187ab859db71fd706a6ea67587b21ad0fe588df Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 31 Jul 2022 09:15:00 +0300 Subject: fork masterminds html5-php --- plugins/af_readability/composer.json | 13 +- plugins/af_readability/composer.lock | 35 +- .../vendor/composer/InstalledVersions.php | 11 +- .../vendor/composer/autoload_psr4.php | 2 +- .../vendor/composer/autoload_static.php | 4 +- .../af_readability/vendor/composer/installed.json | 33 +- .../af_readability/vendor/composer/installed.php | 11 +- .../readability.php/.github/workflows/main.yml | 42 + .../fivefilters/readability.php/composer.json | 9 +- .../readability.php/docker/php/build.Dockerfile | 56 + .../archive-of-our-own/expected-images.json | 1 + .../archive-of-our-own/expected-metadata.json | 8 + .../test-pages/archive-of-our-own/expected.html | 317 + .../test/test-pages/archive-of-our-own/source.html | 1025 +++ .../test/test-pages/citylab-1/expected-images.json | 6 + .../test-pages/citylab-1/expected-metadata.json | 8 + .../test/test-pages/citylab-1/expected.html | 108 + .../test/test-pages/citylab-1/source.html | 683 ++ .../test-pages/data-url-image/expected-images.json | 6 + .../data-url-image/expected-metadata.json | 8 + .../test/test-pages/data-url-image/expected.html | 11 + .../test/test-pages/data-url-image/source.html | 19 + .../test-pages/dropbox-blog/expected-images.json | 5 + .../test-pages/dropbox-blog/expected-metadata.json | 8 + .../test/test-pages/dropbox-blog/expected.html | 527 ++ .../test/test-pages/dropbox-blog/source.html | 868 +++ .../test/test-pages/ebb-org/expected-images.json | 1 + .../test/test-pages/ebb-org/expected-metadata.json | 8 + .../test/test-pages/ebb-org/expected.html | 56 + .../test/test-pages/ebb-org/source.html | 485 ++ .../test/test-pages/folha/expected-images.json | 3 + .../test/test-pages/folha/expected-metadata.json | 8 + .../test/test-pages/folha/expected.html | 24 + .../test/test-pages/folha/source.html | 2518 +++++++ .../google-sre-book-1/expected-images.json | 1 + .../google-sre-book-1/expected-metadata.json | 8 + .../test-pages/google-sre-book-1/expected.html | 458 ++ .../test/test-pages/google-sre-book-1/source.html | 742 ++ .../test-pages/guardian-1/expected-images.json | 16 + .../test-pages/guardian-1/expected-metadata.json | 8 + .../test/test-pages/guardian-1/expected.html | 297 + .../test/test-pages/guardian-1/source.html | 1369 ++++ .../js-link-replacement/expected-images.json | 1 + .../js-link-replacement/expected-metadata.json | 8 + .../test-pages/js-link-replacement/expected.html | 7 + .../test-pages/js-link-replacement/source.html | 14 + .../keep-tabular-data/expected-images.json | 19 + .../keep-tabular-data/expected-metadata.json | 8 + .../test-pages/keep-tabular-data/expected.html | 524 ++ .../test/test-pages/keep-tabular-data/source.html | 740 ++ .../test-pages/lazy-image-1/expected-images.json | 12 + .../test-pages/lazy-image-1/expected-metadata.json | 8 + .../test/test-pages/lazy-image-1/expected.html | 343 + .../test/test-pages/lazy-image-1/source.html | 1277 ++++ .../test-pages/lazy-image-2/expected-images.json | 3 + .../test-pages/lazy-image-2/expected-metadata.json | 8 + .../test/test-pages/lazy-image-2/expected.html | 1108 +++ .../test/test-pages/lazy-image-2/source.html | 3868 +++++++++++ .../test-pages/lazy-image-3/expected-images.json | 4 + .../test-pages/lazy-image-3/expected-metadata.json | 8 + .../test/test-pages/lazy-image-3/expected.html | 8 + .../test/test-pages/lazy-image-3/source.html | 21 + .../medicalnewstoday/expected-images.json | 4 + .../medicalnewstoday/expected-metadata.json | 8 + .../test/test-pages/medicalnewstoday/expected.html | 102 + .../test/test-pages/medicalnewstoday/source.html | 2012 ++++++ .../test/test-pages/mercurial/expected-images.json | 1 + .../test-pages/mercurial/expected-metadata.json | 8 + .../test/test-pages/mercurial/expected.html | 738 ++ .../test/test-pages/mercurial/source.html | 979 +++ .../metadata-content-missing/expected-images.json | 1 + .../expected-metadata.json | 8 + .../metadata-content-missing/expected.html | 19 + .../metadata-content-missing/source.html | 33 + .../normalize-spaces/expected-images.json | 1 + .../normalize-spaces/expected-metadata.json | 8 + .../test/test-pages/normalize-spaces/expected.html | 26 + .../test/test-pages/normalize-spaces/source.html | 35 + .../test/test-pages/nytimes-3/expected-images.json | 11 + .../test-pages/nytimes-3/expected-metadata.json | 8 + .../test/test-pages/nytimes-3/expected.html | 267 + .../test/test-pages/nytimes-3/source.html | 1638 +++++ .../test/test-pages/nytimes-4/expected-images.json | 4 + .../test-pages/nytimes-4/expected-metadata.json | 8 + .../test/test-pages/nytimes-4/expected.html | 214 + .../test/test-pages/nytimes-4/source.html | 3896 +++++++++++ .../remove-aria-hidden/expected-images.json | 1 + .../remove-aria-hidden/expected-metadata.json | 8 + .../test-pages/remove-aria-hidden/expected.html | 7 + .../test/test-pages/remove-aria-hidden/source.html | 19 + .../test-pages/seattletimes-1/expected-images.json | 4 + .../seattletimes-1/expected-metadata.json | 8 + .../test/test-pages/seattletimes-1/expected.html | 179 + .../test/test-pages/seattletimes-1/source.html | 1659 +++++ .../test-pages/topicseed-1/expected-images.json | 3 + .../test-pages/topicseed-1/expected-metadata.json | 8 + .../test/test-pages/topicseed-1/expected.html | 93 + .../test/test-pages/topicseed-1/source.html | 400 ++ .../test/test-pages/v8-blog/expected-images.json | 1 + .../test/test-pages/v8-blog/expected-metadata.json | 8 + .../test/test-pages/v8-blog/expected.html | 178 + .../test/test-pages/v8-blog/source.html | 259 + .../test/test-pages/videos-1/expected-images.json | 3 + .../test-pages/videos-1/expected-metadata.json | 8 + .../test/test-pages/videos-1/expected.html | 309 + .../test/test-pages/videos-1/source.html | 1319 ++++ .../test/test-pages/videos-2/expected-images.json | 3 + .../test-pages/videos-2/expected-metadata.json | 8 + .../test/test-pages/videos-2/expected.html | 107 + .../test/test-pages/videos-2/source.html | 2043 ++++++ .../test-pages/wikipedia-2/expected-images.json | 47 + .../test-pages/wikipedia-2/expected-metadata.json | 8 + .../test/test-pages/wikipedia-2/expected.html | 3107 +++++++++ .../test/test-pages/wikipedia-2/source.html | 7228 ++++++++++++++++++++ .../test-pages/wikipedia-3/expected-images.json | 53 + .../test-pages/wikipedia-3/expected-metadata.json | 8 + .../test/test-pages/wikipedia-3/expected.html | 354 + .../test/test-pages/wikipedia-3/source.html | 3757 ++++++++++ .../vendor/masterminds/html5/.gitattributes | 8 + .../vendor/masterminds/html5/.gitignore | 5 + .../vendor/masterminds/html5/.php_cs.dist | 14 + .../vendor/masterminds/html5/.scrutinizer.yml | 41 + .../vendor/masterminds/html5/.travis.yml | 47 + .../vendor/masterminds/html5/example.php | 32 + .../vendor/masterminds/html5/phpunit.xml.dist | 8 + .../masterminds/html5/test/HTML5/ElementsTest.php | 485 ++ .../html5/test/HTML5/Fixtures/encoding/utf-8.html | 9 + .../test/HTML5/Fixtures/encoding/windows-1252.html | 9 + .../masterminds/html5/test/HTML5/Html5Test.html | 10 + .../masterminds/html5/test/HTML5/Html5Test.php | 492 ++ .../test/HTML5/Parser/CharacterReferenceTest.php | 44 + .../html5/test/HTML5/Parser/DOMTreeBuilderTest.php | 743 ++ .../html5/test/HTML5/Parser/EventStack.php | 116 + .../html5/test/HTML5/Parser/EventStackError.php | 7 + .../test/HTML5/Parser/InstructionProcessorMock.php | 26 + .../html5/test/HTML5/Parser/ScannerTest.php | 184 + .../html5/test/HTML5/Parser/TokenizerTest.php | 978 +++ .../test/HTML5/Parser/TreeBuildingRulesTest.php | 118 + .../html5/test/HTML5/Parser/UTF8UtilsTest.php | 28 + .../test/HTML5/Serializer/OutputRulesTest.php | 652 ++ .../html5/test/HTML5/Serializer/TraverserTest.php | 136 + .../masterminds/html5/test/HTML5/TestCase.php | 23 + .../masterminds/html5/test/benchmark/example.html | 6403 +++++++++++++++++ .../masterminds/html5/test/benchmark/run.php | 29 + 144 files changed, 59632 insertions(+), 56 deletions(-) create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/.github/workflows/main.yml create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/docker/php/build.Dockerfile create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/source.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected-images.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected-metadata.json create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected.html create mode 100644 plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/source.html create mode 100644 plugins/af_readability/vendor/masterminds/html5/.gitattributes create mode 100644 plugins/af_readability/vendor/masterminds/html5/.gitignore create mode 100644 plugins/af_readability/vendor/masterminds/html5/.php_cs.dist create mode 100644 plugins/af_readability/vendor/masterminds/html5/.scrutinizer.yml create mode 100644 plugins/af_readability/vendor/masterminds/html5/.travis.yml create mode 100644 plugins/af_readability/vendor/masterminds/html5/example.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/phpunit.xml.dist create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/ElementsTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Fixtures/encoding/utf-8.html create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Fixtures/encoding/windows-1252.html create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Html5Test.html create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Html5Test.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/CharacterReferenceTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/DOMTreeBuilderTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/EventStack.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/EventStackError.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/InstructionProcessorMock.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/ScannerTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/TokenizerTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/TreeBuildingRulesTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/UTF8UtilsTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Serializer/OutputRulesTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/Serializer/TraverserTest.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/HTML5/TestCase.php create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/benchmark/example.html create mode 100644 plugins/af_readability/vendor/masterminds/html5/test/benchmark/run.php (limited to 'plugins') diff --git a/plugins/af_readability/composer.json b/plugins/af_readability/composer.json index 233f27557..7a7eab59c 100644 --- a/plugins/af_readability/composer.json +++ b/plugins/af_readability/composer.json @@ -1,9 +1,16 @@ { + "minimum-stability": "dev", + "prefer-stable": true, "repositories": [ { - "name": "fivefilters/readability.php", - "type": "vcs", - "url": "https://dev.tt-rss.org/fox/readability-php.git" + "name": "fivefilters/readability.php", + "type": "vcs", + "url": "https://dev.tt-rss.org/fox/readability-php.git" + }, + { + "name": "masterminds/html5", + "type": "vcs", + "url": "https://dev.tt-rss.org/fox/html5-php.git" } ], "require": { diff --git a/plugins/af_readability/composer.lock b/plugins/af_readability/composer.lock index 8b7fea05a..32e78d79f 100644 --- a/plugins/af_readability/composer.lock +++ b/plugins/af_readability/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "351bb4bce6353ca338c03626bab6413f", + "content-hash": "183ed768c66eb8f183350edf06c06a63", "packages": [ { "name": "fivefilters/readability.php", @@ -12,14 +12,14 @@ "source": { "type": "git", "url": "https://dev.tt-rss.org/fox/readability-php.git", - "reference": "5ad152c70376002f043bb936d8ae5eed103fb993" + "reference": "8ac5abdd497b37d2be4833bcf18d6819bba4d9c9" }, "require": { "ext-dom": "*", "ext-mbstring": "*", "ext-xml": "*", "league/uri": "^6.4", - "masterminds/html5": "^2.0", + "masterminds/html5": "2.7.x-dev@dev", "php": ">=7.3.0", "psr/log": "^1.0" }, @@ -64,7 +64,7 @@ "html", "readability" ], - "time": "2022-07-16T13:23:08+00:00" + "time": "2022-07-31T06:02:47+00:00" }, { "name": "league/uri", @@ -238,18 +238,12 @@ }, { "name": "masterminds/html5", - "version": "2.7.5", + "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/Masterminds/html5-php.git", + "url": "https://dev.tt-rss.org/fox/html5-php.git", "reference": "f640ac1bdddff06ea333a920c95bbad8872429ab" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f640ac1bdddff06ea333a920c95bbad8872429ab", - "reference": "f640ac1bdddff06ea333a920c95bbad8872429ab", - "shasum": "" - }, "require": { "ext-ctype": "*", "ext-dom": "*", @@ -259,6 +253,7 @@ "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -270,7 +265,11 @@ "Masterminds\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", + "autoload-dev": { + "psr-4": { + "Masterminds\\HTML5\\Tests\\": "test/HTML5" + } + }, "license": [ "MIT" ], @@ -291,18 +290,14 @@ "description": "An HTML5 parser and serializer.", "homepage": "http://masterminds.github.io/html5-php", "keywords": [ - "HTML5", "dom", "html", + "html5", "parser", "querypath", "serializer", "xml" ], - "support": { - "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.7.5" - }, "time": "2021-07-01T14:25:37+00:00" }, { @@ -466,11 +461,11 @@ ], "packages-dev": [], "aliases": [], - "minimum-stability": "stable", + "minimum-stability": "dev", "stability-flags": { "fivefilters/readability.php": 20 }, - "prefer-stable": false, + "prefer-stable": true, "prefer-lowest": false, "platform": [], "platform-dev": [], diff --git a/plugins/af_readability/vendor/composer/InstalledVersions.php b/plugins/af_readability/vendor/composer/InstalledVersions.php index f11e99676..dff9a52c6 100644 --- a/plugins/af_readability/vendor/composer/InstalledVersions.php +++ b/plugins/af_readability/vendor/composer/InstalledVersions.php @@ -30,7 +30,7 @@ class InstalledVersions 'aliases' => array ( ), - 'reference' => '5006c754c42a09f5b88b258c2da4b9eff7508357', + 'reference' => '4aefbd628e9a0e1eac58523904ad887b0635cda3', 'name' => '__root__', ), 'versions' => @@ -42,7 +42,7 @@ class InstalledVersions 'aliases' => array ( ), - 'reference' => '5006c754c42a09f5b88b258c2da4b9eff7508357', + 'reference' => '4aefbd628e9a0e1eac58523904ad887b0635cda3', ), 'fivefilters/readability.php' => array ( @@ -52,7 +52,7 @@ class InstalledVersions array ( 0 => '9999999-dev', ), - 'reference' => '5ad152c70376002f043bb936d8ae5eed103fb993', + 'reference' => '8ac5abdd497b37d2be4833bcf18d6819bba4d9c9', ), 'league/uri' => array ( @@ -74,10 +74,11 @@ class InstalledVersions ), 'masterminds/html5' => array ( - 'pretty_version' => '2.7.5', - 'version' => '2.7.5.0', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', 'aliases' => array ( + 0 => '2.7.x-dev', ), 'reference' => 'f640ac1bdddff06ea333a920c95bbad8872429ab', ), diff --git a/plugins/af_readability/vendor/composer/autoload_psr4.php b/plugins/af_readability/vendor/composer/autoload_psr4.php index ec14cbb94..bda58c36e 100644 --- a/plugins/af_readability/vendor/composer/autoload_psr4.php +++ b/plugins/af_readability/vendor/composer/autoload_psr4.php @@ -8,7 +8,7 @@ $baseDir = dirname($vendorDir); return array( 'fivefilters\\Readability\\' => array($vendorDir . '/fivefilters/readability.php/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), - 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'Masterminds\\' => array($vendorDir . '/masterminds/html5/src'), 'League\\Uri\\' => array($vendorDir . '/league/uri/src', $vendorDir . '/league/uri-interfaces/src'), ); diff --git a/plugins/af_readability/vendor/composer/autoload_static.php b/plugins/af_readability/vendor/composer/autoload_static.php index b4d70b4f4..a21b92886 100644 --- a/plugins/af_readability/vendor/composer/autoload_static.php +++ b/plugins/af_readability/vendor/composer/autoload_static.php @@ -37,8 +37,8 @@ class ComposerStaticInitb44cc79a0eaef9cd9c2f2ac697cbe9c0 ), 'Psr\\Http\\Message\\' => array ( - 0 => __DIR__ . '/..' . '/psr/http-message/src', - 1 => __DIR__ . '/..' . '/psr/http-factory/src', + 0 => __DIR__ . '/..' . '/psr/http-factory/src', + 1 => __DIR__ . '/..' . '/psr/http-message/src', ), 'Masterminds\\' => array ( diff --git a/plugins/af_readability/vendor/composer/installed.json b/plugins/af_readability/vendor/composer/installed.json index 210558b4a..48dd76515 100644 --- a/plugins/af_readability/vendor/composer/installed.json +++ b/plugins/af_readability/vendor/composer/installed.json @@ -7,14 +7,14 @@ "source": { "type": "git", "url": "https://dev.tt-rss.org/fox/readability-php.git", - "reference": "5ad152c70376002f043bb936d8ae5eed103fb993" + "reference": "8ac5abdd497b37d2be4833bcf18d6819bba4d9c9" }, "require": { "ext-dom": "*", "ext-mbstring": "*", "ext-xml": "*", "league/uri": "^6.4", - "masterminds/html5": "^2.0", + "masterminds/html5": "2.7.x-dev@dev", "php": ">=7.3.0", "psr/log": "^1.0" }, @@ -25,7 +25,7 @@ "suggest": { "monolog/monolog": "Allow logging debug information" }, - "time": "2022-07-16T13:23:08+00:00", + "time": "2022-07-31T06:02:47+00:00", "default-branch": true, "type": "library", "installation-source": "source", @@ -241,19 +241,13 @@ }, { "name": "masterminds/html5", - "version": "2.7.5", - "version_normalized": "2.7.5.0", + "version": "dev-master", + "version_normalized": "dev-master", "source": { "type": "git", - "url": "https://github.com/Masterminds/html5-php.git", + "url": "https://dev.tt-rss.org/fox/html5-php.git", "reference": "f640ac1bdddff06ea333a920c95bbad8872429ab" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f640ac1bdddff06ea333a920c95bbad8872429ab", - "reference": "f640ac1bdddff06ea333a920c95bbad8872429ab", - "shasum": "" - }, "require": { "ext-ctype": "*", "ext-dom": "*", @@ -264,19 +258,24 @@ "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7" }, "time": "2021-07-01T14:25:37+00:00", + "default-branch": true, "type": "library", "extra": { "branch-alias": { "dev-master": "2.7-dev" } }, - "installation-source": "dist", + "installation-source": "source", "autoload": { "psr-4": { "Masterminds\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", + "autoload-dev": { + "psr-4": { + "Masterminds\\HTML5\\Tests\\": "test/HTML5" + } + }, "license": [ "MIT" ], @@ -297,18 +296,14 @@ "description": "An HTML5 parser and serializer.", "homepage": "http://masterminds.github.io/html5-php", "keywords": [ - "HTML5", "dom", "html", + "html5", "parser", "querypath", "serializer", "xml" ], - "support": { - "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.7.5" - }, "install-path": "../masterminds/html5" }, { diff --git a/plugins/af_readability/vendor/composer/installed.php b/plugins/af_readability/vendor/composer/installed.php index 59bb35917..f5d8aae68 100644 --- a/plugins/af_readability/vendor/composer/installed.php +++ b/plugins/af_readability/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '5006c754c42a09f5b88b258c2da4b9eff7508357', + 'reference' => '4aefbd628e9a0e1eac58523904ad887b0635cda3', 'name' => '__root__', ), 'versions' => @@ -18,7 +18,7 @@ 'aliases' => array ( ), - 'reference' => '5006c754c42a09f5b88b258c2da4b9eff7508357', + 'reference' => '4aefbd628e9a0e1eac58523904ad887b0635cda3', ), 'fivefilters/readability.php' => array ( @@ -28,7 +28,7 @@ array ( 0 => '9999999-dev', ), - 'reference' => '5ad152c70376002f043bb936d8ae5eed103fb993', + 'reference' => '8ac5abdd497b37d2be4833bcf18d6819bba4d9c9', ), 'league/uri' => array ( @@ -50,10 +50,11 @@ ), 'masterminds/html5' => array ( - 'pretty_version' => '2.7.5', - 'version' => '2.7.5.0', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', 'aliases' => array ( + 0 => '2.7.x-dev', ), 'reference' => 'f640ac1bdddff06ea333a920c95bbad8872429ab', ), diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/.github/workflows/main.yml b/plugins/af_readability/vendor/fivefilters/readability.php/.github/workflows/main.yml new file mode 100644 index 000000000..3682e6434 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/.github/workflows/main.yml @@ -0,0 +1,42 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + branches: [ master ] + pull_request: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + strategy: + matrix: + php: ['7.3', '7.4', '8'] + libxml: ['2.9.4', '2.9.5', '2.9.10', '2.9.12'] + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # Runs a single command using the runners shell + #- name: Run a one-line script + # run: echo Hello, world! + + # Runs a set of commands using the runners shell + - name: Run a multi-line script + run: | + composer install + docker build --build-arg PHP_VERSION=${{matrix.php}} --build-arg LIBXML_VERSION=${{matrix.libxml}} -t gh-action - < ./docker/php/Dockerfile + docker run --volume $PWD:/app --workdir="/app" --env XDEBUG_MODE=coverage gh-action php ./vendor/bin/phpunit --coverage-clover /app/test/clover.xml diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/composer.json b/plugins/af_readability/vendor/fivefilters/readability.php/composer.json index aba02cf40..72706cca6 100644 --- a/plugins/af_readability/vendor/fivefilters/readability.php/composer.json +++ b/plugins/af_readability/vendor/fivefilters/readability.php/composer.json @@ -5,6 +5,13 @@ "keywords": ["readability", "html"], "homepage": "https://github.com/fivefilters/readability.php", "license": "Apache-2.0", + "repositories": [ + { + "name": "masterminds/html5", + "type": "vcs", + "url": "https://dev.tt-rss.org/fox/html5-php.git" + } + ], "authors": [ { "name": "Andres Rey", @@ -32,7 +39,7 @@ "ext-xml": "*", "ext-mbstring": "*", "psr/log": "^1.0", - "masterminds/html5": "^2.0", + "masterminds/html5": "2.7.x-dev@dev", "league/uri": "^6.4" }, "require-dev": { diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/docker/php/build.Dockerfile b/plugins/af_readability/vendor/fivefilters/readability.php/docker/php/build.Dockerfile new file mode 100644 index 000000000..270b6d99a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/docker/php/build.Dockerfile @@ -0,0 +1,56 @@ +# Use this file to build a Docker image using the versions of PHP and Libxml specified. +# We have pre-built images at https://hub.docker.com/r/fivefilters/php-libxml which are faster to load than building from this file. +# To build using this file, use the following command from the root project folder (replace version of PHP/Libxml with the ones you want to use): +# docker build --build-arg PHP_VERSION=7.4 --build-arg LIBXML_VERSION=2.9.12 -t php-libxml -f ./docker/php/Dockerfile . + +# To upload the image to Docker Hub, the tag (-t) value should be something like org/repo:tag, e.g. for us, fivefilters/php-libxml:php-8-libxml-2.9.12 +# The tag can be applied afterwards too, e.g. docker tag php-libxml org/repo:tag + +ARG PHP_VERSION=8 +FROM php:${PHP_VERSION}-cli + +# Install sqlite and libonig-dev (required for building PHP 7.4) +RUN apt-get update && apt-get install -y libsqlite3-dev libonig-dev +# Install libsodium (package doesn't work for some reason) +RUN curl https://download.libsodium.org/libsodium/releases/LATEST.tar.gz -o /tmp/libsodium.tar.gz && \ + cd /tmp && \ + tar -xzf libsodium.tar.gz && \ + cd libsodium-stable/ && \ + ./configure && \ + make && make check && \ + make install +# Install custom version of libxml2 +RUN apt-get install -y automake libtool unzip libssl-dev +# Remove current version +RUN apt-get remove -y libxml2 +# Download new version, configure and compile +ARG LIBXML_VERSION=2.9.12 +RUN curl https://gitlab.gnome.org/GNOME/libxml2/-/archive/v$LIBXML_VERSION/libxml2-v$LIBXML_VERSION.zip -o /tmp/libxml.zip && \ + cd /tmp && \ + unzip libxml.zip && \ + cd libxml2-v$LIBXML_VERSION && \ + ./autogen.sh --libdir=/usr/lib/x86_64-linux-gnu && \ + make && \ + make install +# Recompile PHP with the new libxml2 library +RUN docker-php-source extract && \ + cd /usr/src/php && \ + ./configure \ + --with-libxml \ + --enable-mbstring \ + --with-openssl \ + --with-config-file-path=/usr/local/etc/php \ + --with-config-file-scan-dir=/usr/local/etc/php/conf.d && \ + make && make install && \ + docker-php-source delete + +RUN apt-get update + +#RUN pecl install libsodium + +# Check if there's a pinned version of Xdebug for compatibility reasons +ARG XDEBUG_VERSION +RUN pecl install xdebug$(if [ ! ${XDEBUG_VERSION} = '' ]; then echo -${XDEBUG_VERSION} ; fi) && docker-php-ext-enable xdebug + +# Required by coveralls +RUN apt-get install git -y diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected-metadata.json new file mode 100644 index 000000000..2f6df8f45 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Organization for Transformative Works", + "Direction": null, + "Excerpt": "An Archive of Our Own, a project of the Organization for Transformative Works", + "Image": null, + "Title": "Conversations with a Cryptid - Chapter 1 - AMournfulHowlInTheNight - \u50d5\u306e\u30d2\u30fc\u30ed\u30fc\u30a2\u30ab\u30c7\u30df\u30a2 | Boku no Hero Academia", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected.html new file mode 100644 index 000000000..d1d1f93ce --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/expected.html @@ -0,0 +1,317 @@ +
+

+ Chapter Text +

+

+ Izuku was struggling to understand how he had even managed to get here, seated before the archvillain of Japan with only a sense of dread to keep him company. All Might sat concealed in an observation room, of the firm opinion that he could only aggravate the prisoner and he sent Izuku off with a strained smile. A vague haze hovered over Izuku’s memory. It started with a simple conversation gone astray on a long drive home. +

+ +

+ “So, who is All For One? Do we know anything about him beyond what you told me before? He’s been imprisoned for months now.” Izuku remembered asking All Might from the backseat of the car as Detective Tsukauchi leisurely drove along a sprawling highway. +

+

+ Playing on the car radio was an aftermath report of a villain attack in downtown Tokyo. Izuku caught the phrase “liquid body” from the female reporter before Detective Tsukauchi changed the channel. +

+

+ “Nope. Still nothing. No one really wants to speak to him,” All Might had replied brightly. “He gives off polite airs, but he’s a piece of work.” All Might’s mostly obstructed shoulders in the front seat shrugged. “Not much you can do with someone like him. Everything that comes out is a threat or taunt.” All Might carefully waved his hand in a circular motion towards the side of his head. +

+

+ “No one’s even made it through a full interview with him, from what I’ve heard,” Detective Tsukauchi added from behind the wheel. “He plays mind games with them. The prison also has a “no recent events” policy on any discussions with him as well. Just in case he ends up with ideas or has some means of communicating. Given that people only want to ask him about current events, it doesn’t leave much to talk about.” +

+

+ “Wait, they still don’t know what Quirks he has?” Izuku asked exasperatedly. “They can’t if there’s still an information block on visits.” +

+

+ “Nope. We have no idea what he can do. They can run DNA tests, but it’s not like anyone apart from him even knows how his Quirk works. They could get matches with any number of people, but if they’re not in a database then we can’t cross-reference them anyway. Even if they run an analysis, the data doesn’t mean anything without the ability to interpret it,” All Might gestured with a skeletal finger. “It’s a waste of time after the initial tests were conducted. They weren’t game to MRI him either, given he’s definitely got a Quirk that creates metal components.” +

+

+ “No one’s bothered to ask him anything about… anything?” Izuku asked, dumbfounded. “He must be around two-hundred years old and people can’t think of a single non-current affairs thing to ask him?” +

+

+ In some ways it was unfathomable that they’d let a potential resource go to waste. On the other hand, said potential resource had blown up a city, murdered numerous people and terrorised Japan for over a century. At the very least. +

+

+ “Well, I tried to ask him about Shigaraki, but he didn’t say much of anything really. Some garbage about you being too dependent on me and him letting Shigaraki run wild and how he just wanted to be the ultimate evil,” All Might shrugged again. “He spends too much time talking about nothing.” +

+

+ Izuku shifted his head onto his arm. “But, that’s not really nothing, is it?” +

+

+ “What do you mean?” Izuku had the feeling that All Might would have been looking at him with the you’re about to do something stupid aren’t you expression that was thankfully becoming less common. +

+

+ “Well, he clearly doesn’t know anything about us, All Might, if he thinks that you’re just going to let go of me after not even two years of being taught. Maybe Shigaraki was dependent on adult figures, but I don’t even remember my dad and mum’s been busy working and keeping the house together. I’ve never had a lot of adult supervision before,” Izuku laughed nervously. “I had to find ways to keep myself entertained. If anything, I’m on the disobedient side of the scale.” All Might outright giggled. +

+

+ “I’ll say, especially after what happened with Overhaul. I’m surprised your mother let you leave the dorms again after that.” +

+

+ “I’m surprised she didn’t withdraw and ground me until I was thirty.” +

+

+ “Oh? That strict?” Tsukauchi asked. +

+

+ “She has her moments,” Izuku smiled fondly. “Do you think she’d agree to me asking the archvillain of Japan about his Quirk?” Izuku asked, only partially joking. There was an itch at the back of his head, a feeling of something missing that poked and prodded at his senses. +

+

+ All Might coughed and sprayed the dash with a fine red mist. “Absolutely not! I forbid it!” +

+

+ “That’s exactly why I’m asking her and not you,” Izuku grinned from the backseat. +

+

+ “He’s evil!” +

+

+ “He’s ancient. You honestly don’t wonder about the sort of things someone with that life experience and Quirk would have run across to end up the way he did?” +

+

+ “Nope, he made it perfectly clear that he always wanted to be the supreme evil,” All Might snipped through folded arms. +

+

+ “Yeah, and I’ll just take his word for that, won’t I?” Izuku grinned. “If he does nothing but lie, then that’s probably one too, but there’s a grain of truth in there somewhere.” +

+

+ “What would you even do? Harass him into telling you his life story?” All Might sighed. +

+

+ “Not when I can kill him with kindness. Who knows, it might even be poisonous for him.” +

+

+ “You’re explaining this to your mother. Teacher or not, I’m not being on the receiving end of this one.” +

+

+ Izuku blinked for a moment. “You’ll let me?” +

+

+ “I’m not entirely for it, but any prospective information on what influenced Shigaraki can only be a good thing. If anything goes south we can pull you out pretty easily. Just be aware of who and what you’re dealing with.” Struggling, All Might turned a serious look to Izuku around the side of the seat. “Only if your mother gives the okay.” +

+

+ The conversation turned to school for the rest of the way. +

+ +

+ It might have been curiosity or it might have been the nagging sensation that chewed at his brain for the three weeks that he researched the subject of the conversation. All For One was a cryptid. Mystical in more ways than one, he was only a rumour on a network that was two-hundred years old. There were whispers of a shadowy figure who once ruled Japan, intermingled with a string of conspiracies and fragmented events. +

+

+ Izuku had even braved the dark web, poking and prodding at some of the seedier elements of the world wide web. The internet had rumours, but the dark web had stories.
+

+

+ An implied yakuza wrote about his grandfather who lost a fire manipulation Quirk and his sanity without any reason. His grandfather had been institutionalised, crying and repeating “he took it, he took it” until his dying days. No one could console him. +

+

+ Another user spoke of a nursing home where a room full of dementia residents inexplicably became docile and no longer used their Quirks on the increasingly disturbed staff. The nursing home erupted into flames just before a court case against them commenced. +

+

+ A user with neon pink text spoke of how their great-great-great-great grandmother with a longevity Quirk had simply aged rapidly one day and passed away in her sleep, her face a mask of terror. No cause had ever been found. +

+

+ A hacker provided a grainy CCTV recording of a heist and a scanned collection of documents from over a century ago, where there was a flash of light and entire bank vault had been emptied. What separated it from the usual robbery was that it contained a list containing confidential information on the Quirks of the First Generation. Izuku had greedily snavelled up and saved the video and documents to an external hard drive. +

+

+ Paging through, Izuku saw someone recount how their Quirkless uncle had developed a warp Quirk and gone from rags to riches under a mysterious benefactor. A decade ago, the uncle had simply disappeared. +

+

+ Numerous and terrifying, the stories were scattered nuggets of gold hidden across the web. They’d never last long, vanishing within hours of posting. Izuku bounced from proxy to proxy, fleeing from a series of deletions that seemed to follow Izuku’s aliased postings across snitch.ru, rabbit.az, aconspiracy.xfiles and their compatriots. +

+

+ After thirty-two identity changes (all carefully logged in a separate notebook), a large amount of feigning communal interest in a lucky tabloid article on All For One which had been released at the start of the first of the three weeks, Izuku hung up his tinfoil hat and called it a month. He haphazardly tossed a bulging notebook into his bookshelf and lodged his hard drive in a gap containing seven others and went to dinner. +

+

+ It took another week to present his research to All Might and Tsukauchi, whose jaws reached the proverbial floor. +

+

+ “We never found any of this,” the Detective Tsukauchi exclaimed. “How did you find all of it?” +

+

+ “I asked the right people. Turns out criminals have very long and very unforgiving memories,” Izuku explained through sunken eyes. “There’s more than this that could be linked to him, but these ones seem to be the most obvious.” +

+

+ “They would do, you can’t be head of the underworld without making an army of enemies,” All Might agreed. “You know, if you can get any more information about these events, I think you’ll give people a lot of peace of mind.” +

+

+ “Provided mum agrees to it.” +

+

+ “Only if she agrees to it.” +

+

+ It took another month to convince his mother, who eventually gave in once All Might provided an extremely comprehensive schedule of how the visitations and any resulting research would be carefully balanced against Izuku’s schoolwork and internship. +

+ +

+ The day of the visit finally arrived, four months after the initial conversation, much to Izuku’s dismay. +

+

+ Izuku remembered how he had arrived, with the Detective and All Might escorting him through its sterile, white innards. A list of rules rattled off at the gate, “no current affairs” was chief among them and an assertion that he’d be dragged from the room if need be if Izuku was to breach any of them. No smuggling of communication devices, no weapons, no Quirks, nothing that could compromise the prisoner’s secure status. +

+

+ Heavily armoured and drilled guards leading him underground into the deepest bowels of the Tartarus complex. +

+

+ Izuku understood the rules, dressed casually in a cotton t-shirt with “Shirt” printed across it in haphazard English and clutching at a carefully screened and utterly blank notebook. +

+

+ Across from him, behind reinforced glass, the archvillain of Japan was bound and unmoving. +

+

+ “Hello,” Izuku initiated uncertainly. His skin had been crawling the moment he crossed the threshold, a memory of the encounter and escape at the Kamino Ward months ago. +

+

+ “Ah, All Might’s disciple,” drawled All For One, “is he too cowardly to come himself? Yet I don’t hear the garments of a hero.” With hardly a word out, All For One had already lunged for the figurative jugular. +

+

+ A stray thought of how does he know who I am if he’s blind and isn’t familiar with me? whispered its way through Izuku’s head. +

+

+ “Oh, no,” Izuku corrected hastily, almost relieved at the lack of any pretence, “I asked if I could talk to you. This isn’t exactly hero related.” +

+

+ “I’m surprised he said yes.” While there was little by way of expression, Izuku could just about sense the contempt dripping from the prisoner’s tone. It wasn’t anything he wasn’t expecting. Kacchan had already said worse to him in earlier years. Water off a duck’s back. +

+

+ “Well, he’s not my legal guardian, so I think you should be more surprised that mum said yes. She’s stricter with these things than All Might,” Izuku corrected again. “Mum gave the okay, but that was a stressful discussion.” And there it was, a miniscule twitch from the man opposite. A spasm more than anything else. Interesting. Pinned down as he was, the prisoner oozed irritation. +

+

+ “At least your mother is a wise person. I wonder why the student doesn’t heed all of the advice of the teacher.” All For One’s tone didn’t indicate a question, so much as an implicit statement that All Might wasn’t worth listening to in any capacity. Kacchan would have hated the comparison, but the hostility had an almost comfortable familiarity. “He no doubt warned you off speaking to me, overprotective as he is, but here you are.” +

+

+ Izuku found himself smiling at the thought of Kacchan’s outrage if he ever found out about the mental comparison as he replied. “I don’t think it’s normal for anyone my age to listen completely to their teachers. We pick and choose and run with what works best for us. He warned me, but I’m still here. Mum warned me as well, but I think she cared more about the time management aspect of it." +

+

+ “Is that a recent development?” All For One probed. +

+

+ “Not really. My old homeroom teacher told me not to bother applying to U.A.” His mother’s beaming face had carried Izuku through the cheerful and resolute signing of that application form. +

+

+ “I see you followed their advice to the letter,” came the snide, dismissive reply. +

+

+ Izuku hoisted up his legs and sat cross-legged in his seat. Leaning slightly forward as he did so as to better prop up his notebook. +

+

+ “You’re a walking contrarian, aren’t you? All Might told me about his run ins with you. What someone does or doesn’t do really doesn’t matter to you, you’ll just find a way to rationalise it as a negative and go on the attack anyway. What you’re currently doing is drawing attention away from yourself and focusing it on me so you can withhold information.” Izuku flipped open his notebook and put pen to paper. “You’ve got something fairly big to hide and you diverting attention exposes that motivation as existing anyway. The only real questions here are what and why?” Izuku paused in mortification as the man opposite’s lips parted. “I just said that aloud, didn’t I?” +

+

+ Of the responses Izuku had expected, it wasn’t laughter. Unrestrained, Izuku would have expected a violent outburst. In this situation, he would have expected another scathing comment. Instead, All For One laughed breathily, leaning into his bonds. Wheezingly he spoke, “I’ll have to change tactics, if that one’s too transparent for you. How refreshing.” +

+

+ Doing his best not to glow a blinding red and simultaneously pale at the interest, Izuku carried on. “I add it to the list when you do. I’m not emotionally involved enough to really be impacted by what you’re saying. I know about you in theory, but that’s it. Maybe All Might has a history with you, but I don’t really know enough about you personally to…” +

+

+ “Care,” All For One supplied, somewhat subdued as he struggled to breathe. “You’re only here to satisfy your curiosity as to whether or not the stories were true.” +

+

+ Izuku nodded, scratching at his notebook with his left hand. “Yes and no, I’m actually here to ask you about how your Quirk works.” For now. +

+

+ Another chortle, more restrained that the last. +

+

+ "What makes you think others haven’t already asked?” Had All For One been unrestrained, Izuku could imagine the stereotypical scene of the villain confidently leaning back in some overblown chair in a secret lair, drink of choice in hand, if the tone of voice was any indication. Deflections aside, the man easily rose to each comment. +

+

+ “Whether or not they asked it’s irrelevant if they can’t read the answers.” Answers didn’t matter if the people involved were too attached to read into the answers. If none of the interviewers had managed a full interview, then it seemed unlikely that any sort of effort was put into understanding the villain. +

+

+ “And you think you can? What expertise do you hold above theirs?” Doubt and reprimand weighted the words. Oddly enough, had Izuku been any younger he could have mistaken the man for a disapproving parent rebuking an overly ambitious child. Albeit an extremely evil one. +

+

+ Izuku inhaled shortly and went for it. “If there’s something I know, it’s Quirks and how they work. Maybe I don’t know you, but I don’t really need to. Quirks fall under broad categories of function. You can take and give, consent doesn’t seem to be a factor. You either can’t “see” certain types of Quirks or you need to have prior knowledge of it before you take it with what I know about your brother. Despite your nom de guerre, because we both know it’s not your real name, you have a history of giving multiple Quirks and causing brain damage to the receiver. You clearly aren’t impacted by those same restrictions, so it must either alter your brain mapping or adjust functions to allow for simultaneous use and storage. It also must isolate or categories the Quirks you stock, because from the few people who do remember you, you creating certain Quirks is always in the context of giving them to someone else meaning there’s probably an inherent immunity to stop it from tainting your own Quirk with a mutation,” Izuku mumbled, almost to himself. “The only thing really in question about your Quirk is the finer details and whether or not you need to maintain those features or if they’re inherent and your hard limit for holding Quirks.” +

+

+ There was silence, for only a moment. “If only my hands were free, I would clap for such a thoughtful assessment. Clearly you’re not all brawn,” All For One positively purred. “Speculate away.” A wide and slightly unhinged smile was directed at Izuku. +

+

+ It was all Izuku could do not to wince at the eagerness. An image of a nervous All Might, hidden in the observation room above with the grim-faced prison staff, came to mind. +

+

+ “I note that you said thoughtful and not correct,” and Izuku breathed and unsteadily jotted it down in his notebook. “You don’t seem bothered by the guess.” +

+

+ “Few people live long enough to question my Quirk, let alone have the talent to guess so thoughtfully at its functions. It seems we share a hobby.” There was something terribly keen in that voice that hadn’t been there before, twisting itself through the compliment. +

+

+ “I suppose it helps that you’re playing along out of boredom,” Izuku verbally dodged, unease uncoiling itself from the back of his mind. +

+

+ “I was playing along out of boredom,” All For One corrected smoothly. “Now, I’m curious. Admittedly, my prior assumptions of you weren’t generous, but I’ve been too hasty in my assessments before.” +

+

+ “I’ll pack up and leave now if that’s the case,” Izuku replied with only half an ear on the conversation as the words on his page began to drastically expand to distract himself from the building anxiety. +

+

+ “Sarcasm, so you do have characteristics of a normal teenager. Your willingness to maim yourself has often left me wondering…” +

+

+ “You’re deflecting again,” Izuku observed. “I’m not sure if that’s a nervous habit for you or if you’re doing it because I’m close to being right about your Quirk. That being said, I don’t think you know what a normal teenager is if Shigaraki is any indication. He’s about seven years too late for his rebellious phase.” +

+

+ “I’m hurt and offended,” came the amused reply. +

+

+ “By how Shigaraki ended up or your parenting? You only have yourself to blame for both of them.” +

+

+ “How harsh. Shigaraki is a product of society that birthed him. I can’t take credit for all of the hard work,” All For One laid out invitingly. Perhaps someone else would have risen to the bait, but Izuku was already packing his mental bags and heading for the door. +

+

+ Clearly the prisoner’s anticipation had registered poorly with someone in the observation room, because a voice rang through the air. “Time’s up Midoriya-kun.” +

+

+ “Okay!” Izuku called back and etched out his last thoughtful of words, untangled his legs and rose to his feet. +

+

+ “What a shame, my visitations are always so short,” All For One spoke mournfully. +

+

+ “Well, you did blow up half a city. They could have just let you suffocate instead. Same time next week, then?” Izuku offered brightly, notebook stuffed into a pocket and was followed out the door by wheezing laughter. +

+

+ It was only after he had made it safely back to the communal room where All Might waited did he allow the spring to fade from his step and discard his nervous smile. Shuddering, he turned to All Might whose face was set in a grimace. +

+

+ “I won’t say I told you so,” All Might offered, perched on the edge of his couch like a misshapen vulture. +

+

+ “He’s… not really what I was expecting. I was expecting someone, more openly evil.” Izuku allowed himself to collapse into the leather of the seat. He shakily reached for the warm tea that had been clearly been prepared the moment Izuku left the cell. “I suppose he does it to lull people into a false sense of security. I didn’t understand how someone with only half a set of expressions could have “villain” written all over them until I met him.” +

+

+ “He’s always been like that. He feigns concern and sympathy to lure in society’s outcasts. They’re easy targets,” All Might said through a mouthful of biscuit. +

+

+ “Has he ever tried it on any of the One For All successors?” +

+

+ “Not really, but you might have accidentally given him the incentive for it. He never had access to any of the One For All wielders while they were young.” All Might snorted, “not that it’ll make a difference with you”. +

+

+ “I think he was trying to gauge me for a world view before the wardens ended it. I need more time to work out his response to the stuff on his Quirk.” +

+

+ “He’s conversation starved since it’s solitary confinement. If what the people monitoring his brain activity said was true, you’re the most exciting thing to have happened to him in months. He replied after you left, said he was looking forward to it.” +

+

+ “That’s pretty sad." +

+

+ “It’s even sadder that we’re the only two members of the public who have had anything to do with him. Stain gets a pile of mail from his “fans”, but All For One has nothing,” All Might waved a tea spoon. “That’s what he gets.” +

+

+ “Let’s get out of here and tell Detective Tsukauchi how it went.” Izuku gulped down his tea and headed for the exit, with him and All Might reaching it at roughly the same amount of time. +

+

+ “At least your mum’s making katsudon for us tonight," was All Might's only optimistic comment. +

+

+ Anxiety was still ebbing over Izuku after Tsukauchi had been debriefed in the car. +

+

+ “It seems we share a hobby.” Haunted Izuku on the drive home. As if ripping someone’s Quirk from them and leaving them lying traumatised on the ground was just a fun pastime and not an act of grievous bodily harm. +

+

+ And he’d be dealing with him again in another week. +

+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/source.html new file mode 100644 index 000000000..5e1d866bd --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/archive-of-our-own/source.html @@ -0,0 +1,1025 @@ + + + + + + + + + + + + + + + + Conversations with a Cryptid - Chapter 1 - AMournfulHowlInTheNight - 僕のヒーローアカデミア | Boku no Hero Academia | My Hero Academia [Archive of Our Own] + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+
+ + + + +
+

+   +

+

+ Actions +

+ +

+ Work Header +

+
+ +
+
+
+

+ Conversations with a Cryptid +

+ + + +
+
+ +
+ + +
+

+ Chapter Text +

+

+ Izuku was struggling to understand how he had even managed to get here, seated before the archvillain of Japan with only a sense of dread to keep him company. All Might sat concealed in an observation room, of the firm opinion that he could only aggravate the prisoner and he sent Izuku off with a strained smile. A vague haze hovered over Izuku’s memory. It started with a simple conversation gone astray on a long drive home. +

+

+   +

+

+ “So, who is All For One? Do we know anything about him beyond what you told me before? He’s been imprisoned for months now.” Izuku remembered asking All Might from the backseat of the car as Detective Tsukauchi leisurely drove along a sprawling highway. +

+

+ Playing on the car radio was an aftermath report of a villain attack in downtown Tokyo. Izuku caught the phrase “liquid body” from the female reporter before Detective Tsukauchi changed the channel. +

+

+ “Nope. Still nothing. No one really wants to speak to him,” All Might had replied brightly. “He gives off polite airs, but he’s a piece of work.” All Might’s mostly obstructed shoulders in the front seat shrugged. “Not much you can do with someone like him. Everything that comes out is a threat or taunt.” All Might carefully waved his hand in a circular motion towards the side of his head. +

+

+ “No one’s even made it through a full interview with him, from what I’ve heard,” Detective Tsukauchi added from behind the wheel. “He plays mind games with them. The prison also has a “no recent events” policy on any discussions with him as well. Just in case he ends up with ideas or has some means of communicating. Given that people only want to ask him about current events, it doesn’t leave much to talk about.” +

+

+ “Wait, they still don’t know what Quirks he has?” Izuku asked exasperatedly. “They can’t if there’s still an information block on visits.” +

+

+ “Nope. We have no idea what he can do. They can run DNA tests, but it’s not like anyone apart from him even knows how his Quirk works. They could get matches with any number of people, but if they’re not in a database then we can’t cross-reference them anyway. Even if they run an analysis, the data doesn’t mean anything without the ability to interpret it,” All Might gestured with a skeletal finger. “It’s a waste of time after the initial tests were conducted. They weren’t game to MRI him either, given he’s definitely got a Quirk that creates metal components.” +

+

+ “No one’s bothered to ask him anything about… anything?” Izuku asked, dumbfounded. “He must be around two-hundred years old and people can’t think of a single non-current affairs thing to ask him?” +

+

+ In some ways it was unfathomable that they’d let a potential resource go to waste. On the other hand, said potential resource had blown up a city, murdered numerous people and terrorised Japan for over a century. At the very least. +

+

+ “Well, I tried to ask him about Shigaraki, but he didn’t say much of anything really. Some garbage about you being too dependent on me and him letting Shigaraki run wild and how he just wanted to be the ultimate evil,” All Might shrugged again. “He spends too much time talking about nothing.” +

+

+ Izuku shifted his head onto his arm. “But, that’s not really nothing, is it?” +

+

+ “What do you mean?” Izuku had the feeling that All Might would have been looking at him with the you’re about to do something stupid aren’t you expression that was thankfully becoming less common. +

+

+ “Well, he clearly doesn’t know anything about us, All Might, if he thinks that you’re just going to let go of me after not even two years of being taught. Maybe Shigaraki was dependent on adult figures, but I don’t even remember my dad and mum’s been busy working and keeping the house together. I’ve never had a lot of adult supervision before,” Izuku laughed nervously. “I had to find ways to keep myself entertained. If anything, I’m on the disobedient side of the scale.” All Might outright giggled. +

+

+ “I’ll say, especially after what happened with Overhaul. I’m surprised your mother let you leave the dorms again after that.” +

+

+ “I’m surprised she didn’t withdraw and ground me until I was thirty.” +

+

+ “Oh? That strict?” Tsukauchi asked. +

+

+ “She has her moments,” Izuku smiled fondly. “Do you think she’d agree to me asking the archvillain of Japan about his Quirk?” Izuku asked, only partially joking. There was an itch at the back of his head, a feeling of something missing that poked and prodded at his senses. +

+

+ All Might coughed and sprayed the dash with a fine red mist. “Absolutely not! I forbid it!” +

+

+ “That’s exactly why I’m asking her and not you,” Izuku grinned from the backseat. +

+

+ “He’s evil!” +

+

+ “He’s ancient. You honestly don’t wonder about the sort of things someone with that life experience and Quirk would have run across to end up the way he did?” +

+

+ “Nope, he made it perfectly clear that he always wanted to be the supreme evil,” All Might snipped through folded arms. +

+

+ “Yeah, and I’ll just take his word for that, won’t I?” Izuku grinned. “If he does nothing but lie, then that’s probably one too, but there’s a grain of truth in there somewhere.” +

+

+ “What would you even do? Harass him into telling you his life story?” All Might sighed. +

+

+ “Not when I can kill him with kindness. Who knows, it might even be poisonous for him.” +

+

+ “You’re explaining this to your mother. Teacher or not, I’m not being on the receiving end of this one.” +

+

+ Izuku blinked for a moment. “You’ll let me?” +

+

+ “I’m not entirely for it, but any prospective information on what influenced Shigaraki can only be a good thing. If anything goes south we can pull you out pretty easily. Just be aware of who and what you’re dealing with.” Struggling, All Might turned a serious look to Izuku around the side of the seat. “Only if your mother gives the okay.” +

+

+ The conversation turned to school for the rest of the way. +

+

+   +

+

+ It might have been curiosity or it might have been the nagging sensation that chewed at his brain for the three weeks that he researched the subject of the conversation. All For One was a cryptid. Mystical in more ways than one, he was only a rumour on a network that was two-hundred years old. There were whispers of a shadowy figure who once ruled Japan, intermingled with a string of conspiracies and fragmented events. +

+

+ Izuku had even braved the dark web, poking and prodding at some of the seedier elements of the world wide web. The internet had rumours, but the dark web had stories.
+

+

+ An implied yakuza wrote about his grandfather who lost a fire manipulation Quirk and his sanity without any reason. His grandfather had been institutionalised, crying and repeating “he took it, he took it” until his dying days. No one could console him. +

+

+ Another user spoke of a nursing home where a room full of dementia residents inexplicably became docile and no longer used their Quirks on the increasingly disturbed staff. The nursing home erupted into flames just before a court case against them commenced. +

+

+ A user with neon pink text spoke of how their great-great-great-great grandmother with a longevity Quirk had simply aged rapidly one day and passed away in her sleep, her face a mask of terror. No cause had ever been found. +

+

+ A hacker provided a grainy CCTV recording of a heist and a scanned collection of documents from over a century ago, where there was a flash of light and entire bank vault had been emptied. What separated it from the usual robbery was that it contained a list containing confidential information on the Quirks of the First Generation. Izuku had greedily snavelled up and saved the video and documents to an external hard drive. +

+

+ Paging through, Izuku saw someone recount how their Quirkless uncle had developed a warp Quirk and gone from rags to riches under a mysterious benefactor. A decade ago, the uncle had simply disappeared. +

+

+ Numerous and terrifying, the stories were scattered nuggets of gold hidden across the web. They’d never last long, vanishing within hours of posting. Izuku bounced from proxy to proxy, fleeing from a series of deletions that seemed to follow Izuku’s aliased postings across snitch.ru, rabbit.az, aconspiracy.xfiles and their compatriots. +

+

+ After thirty-two identity changes (all carefully logged in a separate notebook), a large amount of feigning communal interest in a lucky tabloid article on All For One which had been released at the start of the first of the three weeks, Izuku hung up his tinfoil hat and called it a month. He haphazardly tossed a bulging notebook into his bookshelf and lodged his hard drive in a gap containing seven others and went to dinner. +

+

+ It took another week to present his research to All Might and Tsukauchi, whose jaws reached the proverbial floor. +

+

+ “We never found any of this,” the Detective Tsukauchi exclaimed. “How did you find all of it?” +

+

+ “I asked the right people. Turns out criminals have very long and very unforgiving memories,” Izuku explained through sunken eyes. “There’s more than this that could be linked to him, but these ones seem to be the most obvious.” +

+

+ “They would do, you can’t be head of the underworld without making an army of enemies,” All Might agreed. “You know, if you can get any more information about these events, I think you’ll give people a lot of peace of mind.” +

+

+ “Provided mum agrees to it.” +

+

+ “Only if she agrees to it.” +

+

+ It took another month to convince his mother, who eventually gave in once All Might provided an extremely comprehensive schedule of how the visitations and any resulting research would be carefully balanced against Izuku’s schoolwork and internship. +

+

+   +

+

+ The day of the visit finally arrived, four months after the initial conversation, much to Izuku’s dismay. +

+

+ Izuku remembered how he had arrived, with the Detective and All Might escorting him through its sterile, white innards. A list of rules rattled off at the gate, “no current affairs” was chief among them and an assertion that he’d be dragged from the room if need be if Izuku was to breach any of them. No smuggling of communication devices, no weapons, no Quirks, nothing that could compromise the prisoner’s secure status. +

+

+ Heavily armoured and drilled guards leading him underground into the deepest bowels of the Tartarus complex. +

+

+ Izuku understood the rules, dressed casually in a cotton t-shirt with “Shirt” printed across it in haphazard English and clutching at a carefully screened and utterly blank notebook. +

+

+ Across from him, behind reinforced glass, the archvillain of Japan was bound and unmoving. +

+

+ “Hello,” Izuku initiated uncertainly. His skin had been crawling the moment he crossed the threshold, a memory of the encounter and escape at the Kamino Ward months ago. +

+

+ “Ah, All Might’s disciple,” drawled All For One, “is he too cowardly to come himself? Yet I don’t hear the garments of a hero.” With hardly a word out, All For One had already lunged for the figurative jugular. +

+

+ A stray thought of how does he know who I am if he’s blind and isn’t familiar with me? whispered its way through Izuku’s head. +

+

+ “Oh, no,” Izuku corrected hastily, almost relieved at the lack of any pretence, “I asked if I could talk to you. This isn’t exactly hero related.” +

+

+ “I’m surprised he said yes.” While there was little by way of expression, Izuku could just about sense the contempt dripping from the prisoner’s tone. It wasn’t anything he wasn’t expecting. Kacchan had already said worse to him in earlier years. Water off a duck’s back. +

+

+ “Well, he’s not my legal guardian, so I think you should be more surprised that mum said yes. She’s stricter with these things than All Might,” Izuku corrected again. “Mum gave the okay, but that was a stressful discussion.” And there it was, a miniscule twitch from the man opposite. A spasm more than anything else. Interesting. Pinned down as he was, the prisoner oozed irritation. +

+

+ “At least your mother is a wise person. I wonder why the student doesn’t heed all of the advice of the teacher.” All For One’s tone didn’t indicate a question, so much as an implicit statement that All Might wasn’t worth listening to in any capacity. Kacchan would have hated the comparison, but the hostility had an almost comfortable familiarity. “He no doubt warned you off speaking to me, overprotective as he is, but here you are.” +

+

+ Izuku found himself smiling at the thought of Kacchan’s outrage if he ever found out about the mental comparison as he replied. “I don’t think it’s normal for anyone my age to listen completely to their teachers. We pick and choose and run with what works best for us. He warned me, but I’m still here. Mum warned me as well, but I think she cared more about the time management aspect of it." +

+

+ “Is that a recent development?” All For One probed. +

+

+ “Not really. My old homeroom teacher told me not to bother applying to U.A.” His mother’s beaming face had carried Izuku through the cheerful and resolute signing of that application form. +

+

+ “I see you followed their advice to the letter,” came the snide, dismissive reply. +

+

+ Izuku hoisted up his legs and sat cross-legged in his seat. Leaning slightly forward as he did so as to better prop up his notebook. +

+

+ “You’re a walking contrarian, aren’t you? All Might told me about his run ins with you. What someone does or doesn’t do really doesn’t matter to you, you’ll just find a way to rationalise it as a negative and go on the attack anyway. What you’re currently doing is drawing attention away from yourself and focusing it on me so you can withhold information.” Izuku flipped open his notebook and put pen to paper. “You’ve got something fairly big to hide and you diverting attention exposes that motivation as existing anyway. The only real questions here are what and why?” Izuku paused in mortification as the man opposite’s lips parted. “I just said that aloud, didn’t I?” +

+

+ Of the responses Izuku had expected, it wasn’t laughter. Unrestrained, Izuku would have expected a violent outburst. In this situation, he would have expected another scathing comment. Instead, All For One laughed breathily, leaning into his bonds. Wheezingly he spoke, “I’ll have to change tactics, if that one’s too transparent for you. How refreshing.” +

+

+ Doing his best not to glow a blinding red and simultaneously pale at the interest, Izuku carried on. “I add it to the list when you do. I’m not emotionally involved enough to really be impacted by what you’re saying. I know about you in theory, but that’s it. Maybe All Might has a history with you, but I don’t really know enough about you personally to…” +

+

+ “Care,” All For One supplied, somewhat subdued as he struggled to breathe. “You’re only here to satisfy your curiosity as to whether or not the stories were true.” +

+

+ Izuku nodded, scratching at his notebook with his left hand. “Yes and no, I’m actually here to ask you about how your Quirk works.” For now. +

+

+ Another chortle, more restrained that the last. +

+

+ "What makes you think others haven’t already asked?” Had All For One been unrestrained, Izuku could imagine the stereotypical scene of the villain confidently leaning back in some overblown chair in a secret lair, drink of choice in hand, if the tone of voice was any indication. Deflections aside, the man easily rose to each comment. +

+

+ “Whether or not they asked it’s irrelevant if they can’t read the answers.” Answers didn’t matter if the people involved were too attached to read into the answers. If none of the interviewers had managed a full interview, then it seemed unlikely that any sort of effort was put into understanding the villain. +

+

+ “And you think you can? What expertise do you hold above theirs?” Doubt and reprimand weighted the words. Oddly enough, had Izuku been any younger he could have mistaken the man for a disapproving parent rebuking an overly ambitious child. Albeit an extremely evil one. +

+

+ Izuku inhaled shortly and went for it. “If there’s something I know, it’s Quirks and how they work. Maybe I don’t know you, but I don’t really need to. Quirks fall under broad categories of function. You can take and give, consent doesn’t seem to be a factor. You either can’t “see” certain types of Quirks or you need to have prior knowledge of it before you take it with what I know about your brother. Despite your nom de guerre, because we both know it’s not your real name, you have a history of giving multiple Quirks and causing brain damage to the receiver. You clearly aren’t impacted by those same restrictions, so it must either alter your brain mapping or adjust functions to allow for simultaneous use and storage. It also must isolate or categories the Quirks you stock, because from the few people who do remember you, you creating certain Quirks is always in the context of giving them to someone else meaning there’s probably an inherent immunity to stop it from tainting your own Quirk with a mutation,” Izuku mumbled, almost to himself. “The only thing really in question about your Quirk is the finer details and whether or not you need to maintain those features or if they’re inherent and your hard limit for holding Quirks.” +

+

+ There was silence, for only a moment. “If only my hands were free, I would clap for such a thoughtful assessment. Clearly you’re not all brawn,” All For One positively purred. “Speculate away.” A wide and slightly unhinged smile was directed at Izuku. +

+

+ It was all Izuku could do not to wince at the eagerness. An image of a nervous All Might, hidden in the observation room above with the grim-faced prison staff, came to mind. +

+

+ “I note that you said thoughtful and not correct,” and Izuku breathed and unsteadily jotted it down in his notebook. “You don’t seem bothered by the guess.” +

+

+ “Few people live long enough to question my Quirk, let alone have the talent to guess so thoughtfully at its functions. It seems we share a hobby.” There was something terribly keen in that voice that hadn’t been there before, twisting itself through the compliment. +

+

+ “I suppose it helps that you’re playing along out of boredom,” Izuku verbally dodged, unease uncoiling itself from the back of his mind. +

+

+ “I was playing along out of boredom,” All For One corrected smoothly. “Now, I’m curious. Admittedly, my prior assumptions of you weren’t generous, but I’ve been too hasty in my assessments before.” +

+

+ “I’ll pack up and leave now if that’s the case,” Izuku replied with only half an ear on the conversation as the words on his page began to drastically expand to distract himself from the building anxiety. +

+

+ “Sarcasm, so you do have characteristics of a normal teenager. Your willingness to maim yourself has often left me wondering…” +

+

+ “You’re deflecting again,” Izuku observed. “I’m not sure if that’s a nervous habit for you or if you’re doing it because I’m close to being right about your Quirk. That being said, I don’t think you know what a normal teenager is if Shigaraki is any indication. He’s about seven years too late for his rebellious phase.” +

+

+ “I’m hurt and offended,” came the amused reply. +

+

+ “By how Shigaraki ended up or your parenting? You only have yourself to blame for both of them.” +

+

+ “How harsh. Shigaraki is a product of society that birthed him. I can’t take credit for all of the hard work,” All For One laid out invitingly. Perhaps someone else would have risen to the bait, but Izuku was already packing his mental bags and heading for the door. +

+

+ Clearly the prisoner’s anticipation had registered poorly with someone in the observation room, because a voice rang through the air. “Time’s up Midoriya-kun.” +

+

+ “Okay!” Izuku called back and etched out his last thoughtful of words, untangled his legs and rose to his feet. +

+

+ “What a shame, my visitations are always so short,” All For One spoke mournfully. +

+

+ “Well, you did blow up half a city. They could have just let you suffocate instead. Same time next week, then?” Izuku offered brightly, notebook stuffed into a pocket and was followed out the door by wheezing laughter. +

+

+ It was only after he had made it safely back to the communal room where All Might waited did he allow the spring to fade from his step and discard his nervous smile. Shuddering, he turned to All Might whose face was set in a grimace. +

+

+ “I won’t say I told you so,” All Might offered, perched on the edge of his couch like a misshapen vulture. +

+

+ “He’s… not really what I was expecting. I was expecting someone, more openly evil.” Izuku allowed himself to collapse into the leather of the seat. He shakily reached for the warm tea that had been clearly been prepared the moment Izuku left the cell. “I suppose he does it to lull people into a false sense of security. I didn’t understand how someone with only half a set of expressions could have “villain” written all over them until I met him.” +

+

+ “He’s always been like that. He feigns concern and sympathy to lure in society’s outcasts. They’re easy targets,” All Might said through a mouthful of biscuit. +

+

+ “Has he ever tried it on any of the One For All successors?” +

+

+ “Not really, but you might have accidentally given him the incentive for it. He never had access to any of the One For All wielders while they were young.” All Might snorted, “not that it’ll make a difference with you”. +

+

+ “I think he was trying to gauge me for a world view before the wardens ended it. I need more time to work out his response to the stuff on his Quirk.” +

+

+ “He’s conversation starved since it’s solitary confinement. If what the people monitoring his brain activity said was true, you’re the most exciting thing to have happened to him in months. He replied after you left, said he was looking forward to it.” +

+

+ “That’s pretty sad." +

+

+ “It’s even sadder that we’re the only two members of the public who have had anything to do with him. Stain gets a pile of mail from his “fans”, but All For One has nothing,” All Might waved a tea spoon. “That’s what he gets.” +

+

+ “Let’s get out of here and tell Detective Tsukauchi how it went.” Izuku gulped down his tea and headed for the exit, with him and All Might reaching it at roughly the same amount of time. +

+

+ “At least your mum’s making katsudon for us tonight," was All Might's only optimistic comment. +

+

+ Anxiety was still ebbing over Izuku after Tsukauchi had been debriefed in the car. +

+

+ “It seems we share a hobby.” Haunted Izuku on the drive home. As if ripping someone’s Quirk from them and leaving them lying traumatised on the ground was just a fun pastime and not an act of grievous bodily harm. +

+

+ And he’d be dealing with him again in another week. +

+
+
+
+
+
+ + + + +
+ +
+
+
+ +
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected-images.json new file mode 100644 index 000000000..8a74adf2f --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected-images.json @@ -0,0 +1,6 @@ +[ + "https:\/\/cdn.citylab.com\/media\/img\/citylab\/2019\/04\/mr1\/facebook.jpg?1556645448", + "https:\/\/cdn.citylab.com\/media\/img\/citylab\/2019\/04\/mr1\/300.jpg?mod=1556645448", + "https:\/\/cdn.theatlantic.com\/assets\/media\/img\/posts\/2019\/04\/AP_8912060228\/cbd32b0e1.jpg", + "https:\/\/cdn.theatlantic.com\/assets\/media\/img\/posts\/2019\/04\/AP_945361213236\/888fdd750.jpg" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected-metadata.json new file mode 100644 index 000000000..6ec809e6b --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Sarah Archer", + "Direction": null, + "Excerpt": "The once-ubiquitous form of lighting was novel when it first emerged in the early 1900s, though it has since come to represent decline.", + "Image": "https:\/\/cdn.citylab.com\/media\/img\/citylab\/2019\/04\/mr1\/facebook.jpg?1556645448", + "Title": "The Modern Ambitions Behind Neon", + "SiteName": "CityLab" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected.html new file mode 100644 index 000000000..2ad9f8673 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/expected.html @@ -0,0 +1,108 @@ +
+ + + + +
+ + + + +
+ The Moulin Rouge cabaret in Paris Benoit Tessier/Reuters +
+
+
+

+ Why Neon Is the Ultimate Symbol of the 20th Century +

+ +
+

+ The once-ubiquitous form of lighting was novel when it first emerged in the early 1900s, though it has since come to represent decline. +

+ +
+

+ In the summer of 1898, the Scottish chemist Sir William Ramsay made a discovery that would eventually give the Moulin Rouge in Paris, the Las Vegas Strip, and New York’s Times Square their perpetual nighttime glow. Using the boiling point of argon as a reference point, Ramsay and his colleague Morris W. Travers isolated three more noble gases and gave them evocative Greek names: neon, krypton, and xenon. In so doing, the scientists bestowed a label of permanent novelty on the most famous of the trio—neon, which translates as “new.” This discovery was the foundation on which the French engineer Georges Claude crafted a new form of illumination over the next decade. He designed glass tubes in which neon gas could be trapped, then electrified, to create a light that glowed reliably for more than 1,000 hours. +

+

+ In the 2012 book L’être et le Néon, which has been newly translated into English by Michael Wells, the philosopher Luis de Miranda weaves a history of neon lighting as both artifact and metaphor. Being and Neonness, as the book is called in its English edition, isn’t a typical material history. There are no photographs. Even de Miranda’s own example of a neon deli sign spotted in Paris is re-created typographically, with text in all caps and dashes forming the border of the sign, as one might attempt on Twitter. Fans of Miami Beach’s restored Art Deco hotels and California’s bowling alleys might be disappointed by the lack of glossy historical images. Nonetheless, de Miranda makes a convincing case for neon as a symbol of the grand modern ambitions of the 20th century. +

+ +

+ De Miranda beautifully evokes the notion of neon lighting as an icon of the 1900s in his introduction: “When we hear the word neon, an image pops into our heads: a combination of light, colors, symbols, and glass. This image is itself a mood. It carries an atmosphere. It speaks … of the essence of cities, of the poetry of nights, of the 20th century.” When neon lights debuted in Europe, they seemed dazzlingly futuristic. But their husky physicality started becoming obsolete by the 1960s, thanks in part to the widespread use of plastic for fluorescent signs. Neon signs exist today, though they’ve been eclipsed by newer technologies such as digital billboards, and they remain charmingly analog: Signs must be made by hand because there’s no cost-effective way to mass-produce them. +

+

+ In the 1910s, neon started being used for cosmopolitan flash in Paris at precisely the time and place where the first great modernist works were being created. De Miranda’s recounting of the ingenuity emerging from the French capital a century ago is thrilling to contemplate: the cubist art of Pablo Picasso, the radically deconstructed fashions of Coco Chanel, the stream-of-consciousness poetry of Gertrude Stein, and the genre-defying music of Claude Debussy—all of which heralded a new age of culture for Europe and for the world. +

+
+ +
+

+ Amid this artistic groundswell, Georges Claude premiered his neon lights at the Paris Motor Show in December 1910, captivating visitors with 40-foot-tall tubes affixed to the building’s exterior. The lights shone orange-red because neon, by itself, produces that color. Neon lighting is a catchall term that describes the technology of glass tubing that contains gas or chemicals that glow when electrified. For example, neon fabricators use carbon dioxide to make white, and mercury to make blue. Claude acknowledged at the time that neon didn’t produce the ideal color for a standard light bulb and insisted that it posed no commercial threat to incandescent bulbs. +

+

+ Of course, the very quality that made neon fixtures a poor choice for interior lighting made them perfect for signs, de Miranda notes. The first of the neon signs was switched on in 1912, advertising a barbershop on Paris’s Boulevard Montmartre, and eventually they were adopted by cinemas and nightclubs. While Claude had a monopoly on neon lighting throughout the 1920s, the leaking of trade secrets and the expiration of a series of patents broke his hold on the rapidly expanding technology. +

+
+ +
+

+ In the following decades, neon’s nonstop glow and vibrant colors turned ordinary buildings and surfaces into 24/7 billboards for businesses, large and small, that wanted to convey a sense of always being open. The first examples of neon in the United States debuted in Los Angeles, where the Packard Motor Car Company commissioned two large blue-and-orange Packard signs that literally stopped traffic because they distracted motorists. The lighting also featured heavily at the Chicago Century of Progress Exposition in 1933 and at the 1939 World’s Fair in New York. At the latter event, a massive neon sign reading Futurama lit the way to a General Motors exhibition that heralded “The World of Tomorrow.” +

+
+ +
+ Workers remove a hammer and sickle from a neon sign that reads “Glory to Communism,” visible on the roof of the Communist-run electricity-board headquarters in Czechoslovakia in 1989. (AP) +
+
+

+ De Miranda points out that businesses weren’t alone in embracing neon’s ability to spread messages effectively. By the middle of the century, the lighting was being adopted for more political purposes. “In the 1960s, the Soviets deployed a vast ‘neonization’ of the Eastern bloc capitals to emulate capitalist metropolises,” de Miranda writes. “Because consumer shops were rare in the Polish capital [of Warsaw], they did not hesitate to illuminate the façades of public buildings.” In other words, as opposed to the sole use of the more obvious forms of propaganda via posters or slogans, the mass introduction of neon lighting was a way of getting citizens of Communist cities to see their surroundings with the pizzazz and nighttime glamour of major Western capitals. +

+
+ +
+

+ Neon, around this time, began to be phased out, thanks to cheaper and less labor-intensive alternatives. In addition, the global economic downturn of the 1970s yielded a landscape in which older, flickering neon signs, which perhaps their owners couldn’t afford to fix or replace, came to look like symbols of decline. Where such signs were once sophisticated and novel, they now seemed dated and even seedy. +

+
+

+ Cities are changing fast. Keep up with the CityLab Daily newsletter. +

+ +
+

+ De Miranda understands this evolution by zooming out and looking at the 1900s as the “neon century.” The author draws a parallel between the physical form of neon lights, which again are essentially containers for electrified gases, and that of a glass capsule—suggesting they are a kind of message in a bottle from a time before the First World War. “Since then, [neon lights] have witnessed all the transformations that have created the world we live in,” de Miranda writes. “Today, they sometimes seem to maintain a hybrid status, somewhere between junkyards and museums, not unlike European capitals themselves.” +

+
+ +
+ Martin Wartman, a student at Northern Kentucky University, works on a neon sign at the Neonworks of Cincinnati workshop connected to the American Sign Museum, in 2016. (John Minchillo / AP) +
+
+

+ Another mark of neon’s hybridity: Its obsolescence started just as some contemporary artists began using the lights in their sculptures. Bruce Nauman’s 1968 work My Name as Though It Were Written on the Surface of the Moon poked fun at the space race—another symbol of 20th-century technological innovation whose moment has passed. The piece uses blue “neon” letters (mercury, actually) to spell out the name “bruce” in lowercase cursive, with each character repeated several times as if to convey a person speaking slowly in outer space. The British artist Tracey Emin has made sculptures that resemble neon Valentine’s Day candies: They read as garish and sentimental confections with pink, heart-shaped frames that surround blue text fragments. Drawing on the nostalgia-inducing quality of neon, the sculptures’ messages are redolent of old-fashioned movie dialogue, with titles such as “You Loved Me Like a Distant Star” and “The Kiss Was Beautiful.” +

+

+ Seeing neon lighting tamed in the context of a gallery display fits comfortably with de Miranda’s notion that neon technology is like a time capsule from another age. In museums, works of neon art and design coexist with objects that were ahead of their own time in years past—a poignant fate for a technology that made its name advertising “The World of Tomorrow.” Yet today neon is also experiencing a kind of craft revival. The fact that it can’t be mass-produced has made its fabrication something akin to a cherished artisanal technique. Bars and restaurants hire firms such as Let There Be Neon in Manhattan, or the L.A.-based master neon artist Lisa Schulte, to create custom signs and works of art. Neon’s story even continues to glow from inside museums such as California’s Museum of Neon Art and the Neon Museum in Las Vegas. If it can still be a vital medium for artists and designers working today, “neonness” need not only be trapped in the past. It might also capture the mysterious glow of the near future—just as it did a century ago. +

+

+ This article originally appeared on The Atlantic. +

+
+
+

+ About the Author +

+ +
+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/source.html new file mode 100644 index 000000000..710206187 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/citylab-1/source.html @@ -0,0 +1,683 @@ + + + + + + + A Brief History of Neon Signage - CityLab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+ + + +
+ + +
+ +
+
+
+ + + + +
+ The Moulin Rouge cabaret in Paris Benoit Tessier/Reuters +
+
+ +

+ The once-ubiquitous form of lighting was novel when it first emerged in the early 1900s, though it has since come to represent decline. +

+
+ +
+
+

+ In the summer of 1898, the Scottish chemist Sir William Ramsay made a discovery that would eventually give the Moulin Rouge in Paris, the Las Vegas Strip, and New York’s Times Square their perpetual nighttime glow. Using the boiling point of argon as a reference point, Ramsay and his colleague Morris W. Travers isolated three more noble gases and gave them evocative Greek names: neon, krypton, and xenon. In so doing, the scientists bestowed a label of permanent novelty on the most famous of the trio—neon, which translates as “new.” This discovery was the foundation on which the French engineer Georges Claude crafted a new form of illumination over the next decade. He designed glass tubes in which neon gas could be trapped, then electrified, to create a light that glowed reliably for more than 1,000 hours. +

+

+ In the 2012 book L’être et le Néon, which has been newly translated into English by Michael Wells, the philosopher Luis de Miranda weaves a history of neon lighting as both artifact and metaphor. Being and Neonness, as the book is called in its English edition, isn’t a typical material history. There are no photographs. Even de Miranda’s own example of a neon deli sign spotted in Paris is re-created typographically, with text in all caps and dashes forming the border of the sign, as one might attempt on Twitter. Fans of Miami Beach’s restored Art Deco hotels and California’s bowling alleys might be disappointed by the lack of glossy historical images. Nonetheless, de Miranda makes a convincing case for neon as a symbol of the grand modern ambitions of the 20th century. +

+ +

+ De Miranda beautifully evokes the notion of neon lighting as an icon of the 1900s in his introduction: “When we hear the word neon, an image pops into our heads: a combination of light, colors, symbols, and glass. This image is itself a mood. It carries an atmosphere. It speaks … of the essence of cities, of the poetry of nights, of the 20th century.” When neon lights debuted in Europe, they seemed dazzlingly futuristic. But their husky physicality started becoming obsolete by the 1960s, thanks in part to the widespread use of plastic for fluorescent signs. Neon signs exist today, though they’ve been eclipsed by newer technologies such as digital billboards, and they remain charmingly analog: Signs must be made by hand because there’s no cost-effective way to mass-produce them. +

+

+ In the 1910s, neon started being used for cosmopolitan flash in Paris at precisely the time and place where the first great modernist works were being created. De Miranda’s recounting of the ingenuity emerging from the French capital a century ago is thrilling to contemplate: the cubist art of Pablo Picasso, the radically deconstructed fashions of Coco Chanel, the stream-of-consciousness poetry of Gertrude Stein, and the genre-defying music of Claude Debussy—all of which heralded a new age of culture for Europe and for the world. +

+
+ +
+

+ Amid this artistic groundswell, Georges Claude premiered his neon lights at the Paris Motor Show in December 1910, captivating visitors with 40-foot-tall tubes affixed to the building’s exterior. The lights shone orange-red because neon, by itself, produces that color. Neon lighting is a catchall term that describes the technology of glass tubing that contains gas or chemicals that glow when electrified. For example, neon fabricators use carbon dioxide to make white, and mercury to make blue. Claude acknowledged at the time that neon didn’t produce the ideal color for a standard light bulb and insisted that it posed no commercial threat to incandescent bulbs. +

+

+ Of course, the very quality that made neon fixtures a poor choice for interior lighting made them perfect for signs, de Miranda notes. The first of the neon signs was switched on in 1912, advertising a barbershop on Paris’s Boulevard Montmartre, and eventually they were adopted by cinemas and nightclubs. While Claude had a monopoly on neon lighting throughout the 1920s, the leaking of trade secrets and the expiration of a series of patents broke his hold on the rapidly expanding technology. +

+
+
+
+

+ In the following decades, neon’s nonstop glow and vibrant colors turned ordinary buildings and surfaces into 24/7 billboards for businesses, large and small, that wanted to convey a sense of always being open. The first examples of neon in the United States debuted in Los Angeles, where the Packard Motor Car Company commissioned two large blue-and-orange Packard signs that literally stopped traffic because they distracted motorists. The lighting also featured heavily at the Chicago Century of Progress Exposition in 1933 and at the 1939 World’s Fair in New York. At the latter event, a massive neon sign reading Futurama lit the way to a General Motors exhibition that heralded “The World of Tomorrow.” +

+
+ +
+ Workers remove a hammer and sickle from a neon sign that reads “Glory to Communism,” visible on the roof of the Communist-run electricity-board headquarters in Czechoslovakia in 1989. (AP) +
+
+

+ De Miranda points out that businesses weren’t alone in embracing neon’s ability to spread messages effectively. By the middle of the century, the lighting was being adopted for more political purposes. “In the 1960s, the Soviets deployed a vast ‘neonization’ of the Eastern bloc capitals to emulate capitalist metropolises,” de Miranda writes. “Because consumer shops were rare in the Polish capital [of Warsaw], they did not hesitate to illuminate the façades of public buildings.” In other words, as opposed to the sole use of the more obvious forms of propaganda via posters or slogans, the mass introduction of neon lighting was a way of getting citizens of Communist cities to see their surroundings with the pizzazz and nighttime glamour of major Western capitals. +

+
+
+
+

+ Neon, around this time, began to be phased out, thanks to cheaper and less labor-intensive alternatives. In addition, the global economic downturn of the 1970s yielded a landscape in which older, flickering neon signs, which perhaps their owners couldn’t afford to fix or replace, came to look like symbols of decline. Where such signs were once sophisticated and novel, they now seemed dated and even seedy. +

+ +

+ De Miranda understands this evolution by zooming out and looking at the 1900s as the “neon century.” The author draws a parallel between the physical form of neon lights, which again are essentially containers for electrified gases, and that of a glass capsule—suggesting they are a kind of message in a bottle from a time before the First World War. “Since then, [neon lights] have witnessed all the transformations that have created the world we live in,” de Miranda writes. “Today, they sometimes seem to maintain a hybrid status, somewhere between junkyards and museums, not unlike European capitals themselves.” +

+
+ +
+ Martin Wartman, a student at Northern Kentucky University, works on a neon sign at the Neonworks of Cincinnati workshop connected to the American Sign Museum, in 2016. (John Minchillo / AP) +
+
+

+ Another mark of neon’s hybridity: Its obsolescence started just as some contemporary artists began using the lights in their sculptures. Bruce Nauman’s 1968 work My Name as Though It Were Written on the Surface of the Moon poked fun at the space race—another symbol of 20th-century technological innovation whose moment has passed. The piece uses blue “neon” letters (mercury, actually) to spell out the name “bruce” in lowercase cursive, with each character repeated several times as if to convey a person speaking slowly in outer space. The British artist Tracey Emin has made sculptures that resemble neon Valentine’s Day candies: They read as garish and sentimental confections with pink, heart-shaped frames that surround blue text fragments. Drawing on the nostalgia-inducing quality of neon, the sculptures’ messages are redolent of old-fashioned movie dialogue, with titles such as “You Loved Me Like a Distant Star” and “The Kiss Was Beautiful.” +

+

+ Seeing neon lighting tamed in the context of a gallery display fits comfortably with de Miranda’s notion that neon technology is like a time capsule from another age. In museums, works of neon art and design coexist with objects that were ahead of their own time in years past—a poignant fate for a technology that made its name advertising “The World of Tomorrow.” Yet today neon is also experiencing a kind of craft revival. The fact that it can’t be mass-produced has made its fabrication something akin to a cherished artisanal technique. Bars and restaurants hire firms such as Let There Be Neon in Manhattan, or the L.A.-based master neon artist Lisa Schulte, to create custom signs and works of art. Neon’s story even continues to glow from inside museums such as California’s Museum of Neon Art and the Neon Museum in Las Vegas. If it can still be a vital medium for artists and designers working today, “neonness” need not only be trapped in the past. It might also capture the mysterious glow of the near future—just as it did a century ago. +

+

+ This article originally appeared on The Atlantic. +

+
+
+

+ About the Author +

+ +
+
+
+ +
+
+ +
+

+ Most Popular +

+
+
    +
  1. + A photo of an Uber Bus in Cairo, the company's new microtransit program. +
    + Transportation +

    + ‘Uber Was Supposed To Be Our Public Transit’ +

    +

    + Innisfil, Ontario, decided to partially subsidize ride-hailing trips rather than pay for a public bus system. It worked so well that now they have to raise fares and cap rides. +

    + +
    +
  2. +
  3. + +
    + Environment +

    + A 13,235-Mile Road Trip for 70-Degree Weather Every Day +

    +

    + This year-long journey across the U.S. keeps you at consistent high temperatures. +

    + +
    +
  4. +
  5. + The outside of a large apartment building, dotted with air conditioners. +
    + Environment +

    + What If Air Conditioning Could Help Stop Climate Change Instead of Causing It? +

    +

    + Using technology currently in development, AC units in skyscrapers and homes could get turned into machines that pull carbon dioxide out of the atmosphere. +

    + +
    +
  6. +
  7. + A train traveling on an elevated platform. +
    + Transportation +

    + Texas High Speed Rail Faces a New Threat: Semantics +

    +

    + A private company plans to break ground on a bullet train between Houston and Dallas in 2019. But opponents of the project have a new argument. +

    + +
    +
  8. +
  9. + +
    + Solutions +

    + In Switzerland, Everyone’s an Urban Planner +

    +

    + To reimagine its largest public space, the Swiss city of Lausanne organized a citywide consultation and workshop that asked: Just who is the public? +

    + +
    +
  10. +
+
+
+
+
+ +
+
+ Maps +
Click Here +
+
+
+ + +
+
+ + +
+
+
+
+
+ + + +
+
+ Popular Now on CityLab » +
+
+
+
+
+ +
+ +
+ + + + + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected-images.json new file mode 100644 index 000000000..b85fb67d7 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected-images.json @@ -0,0 +1,6 @@ +[ + "data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==", + "data:image\/svg+xml;utf8,<\/svg>", + "data:image\/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAyNCAyNCc+PHBhdGggZD0nTTUxMiA1MTJIMFYwaDUxMnY1MTJ6Jy8+PC9zdmc+", + "data:image\/jpeg;base64,\/9j\/4AAQSkZJRgABAQEBLAEsAAD\/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj\/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj\/wAARCAH0AbYDAREAAhEBAxEB\/8QAHAAAAgMBAQEBAAAAAAAAAAAABAUCAwYBBwAI\/8QASRAAAgEDAgMGAwYEBAQFAwMFAQIDAAQREiEFMUEGEyJRYXEygZEUI0KhscEHUmLRM3Lh8BUkQ\/EIFjQ1glOiwkVjgyUmkrKz\/8QAGwEAAwEBAQEBAAAAAAAAAAAAAAECAwQFBgf\/xAA1EQACAgICAgEDAwEHBQEAAwAAAQIRAyESMQRBURMiYQUycYEGIzORobHRFELB4fAVUoLx\/9oADAMBAAIRAxEAPwD1G3lC9a8Hjs4LLnvCq896HAdgzcSKnGalx2FnW4lkc81tGArKDxI6uZFOcPgEwqG\/JxhtzWPFpjCBe7bmjaAsS665+VJx+APpLvbGcVpFfImCi7wTvV6DYRBcvnc7VLiOw6O6x1rLiUmfSXy43b51Sr2Ps8n\/AIiTifi5wSQN9\/aujDtnXgVI0PAgV4ZAP6B+lelDpA+zPdvT4I\/Ws8vo0xmGxmsjcLsB\/wAwtAUP2+GpYkCSjfepsYou9pjyqwZCmxF5yIIzvgvil3sAgZwKoCQNKvkR6H\/CJ8cQul81BrfB2zHN6PY7XwO2SNxS8t1CzGHYbzVfKowO4JmjAL9iWORgCtWIS3rpHkkgnGSOtIDG9qiGvLfG4NZ5PRcBhaDEK+1UiWScc6YCbivWpfQ0Hdl1LSYAJPPYVpjJkaiOWJ5AiTQs+caRKufpmtOSurJ4Sq6PP\/4n7r3bZB2GOuaif7lY10egdnLsJwCyGRkRL+leZmVCTCJb4E7nFckk2UVHiEaHJPzpK0FnV4mhOAarfYrD4LpXALeVWmwsm9ytQ2xlbXaBSM1DegKWvEJxkVkpjKheIpO9VdiPpLxG8qmxlcd4A2CKFkaETmvV0HcVSyWApm4npc5PKtI9gVycR1dMmuutEXYG96wf1rKYrC4LxicsaxeSh0Evfrp3xmnCbbHoBe+yxwNVdUc0kiXFMQrcELk4Hzo4HHZS96GYgZqq0AHPMc8z60kkBUkzBcA7k1URIr786\/izimAbBd4G5FQ4XsZyTiHiCqaniUFW15k75J8qFGwYW0xKZ5U3DRNlYZsg74ppUFl6zkHYkelOkFk2uiqnVn5UmkNFPfaxsazcfZaZ572tbPF5QeldGPo7sP7TZ8G\/9uh\/yD9K9CPSJZm+3vwQj3rLL6NMS2YnArI3DOHj79aTF6HxG1SxA0g33pdlIS3I++arQyFUSFNHmyQgcpKliZbp2GKY+ztAqNr\/AAuk0cWnH\/7efzrbC\/uMsy0ew3kxS1DA7nrmp87\/AAWYR7Gtg5e1gYncoDU+N\/hx\/gso4kCVYdcVuwMle8O7ziH2nvHyU06TnHvWdK7Az3aRcX9uo3AFTk7RcRpaj7oe1WiTr9aQCXiekBnlcRxL8THp\/c0m0k2yoxcnSFqXk9xEYoiYLQnZV2Z\/VjXBk8iUtLSPQhgjDbVstj4cjKSM5NYUbcgPtCZb7gZjuCXuLMgq7HLNGTuD7Eg+xr0PGy81xl2jh8nEovnHpmls7trfhltGzY0oBzpZ4qzz72yM3FMnAbeuZ40WVy3bSLuedJxSEGWhYKCSdq0jEQyivsYXNEoWBa9+qJnVWTxhyF8182SdRxWc8aHZQ3ESE3ORWPALB\/8AiX3nifw1axsakEHiSso0tT+m6HZWOIrvqaspY2guzk3ERpxrqIQt9B0Kbq9GQxO2a7seOkS3ZKG7IX4se9NiRclyHILEE1lNNdD0EpcgHANc80CK5LhjJsdjXRGOrQrCLZtWTiom2NMTSgjbFd9HCDDCEnH1pUAHcXBBIANGwBzIzEAHc+VKx0WrFhck74pAUSOynnsfI07GVLPpPWnfpDoZWMraQSd6VEsYJdquM04iLY7xG5HPkKdUMuMxK7Del\/I6KCXZwNxUsYbBFgb\/ACoSoRgO1i6eKyE9Sa1gehgf2m04UMWMP+UfpXcukSzL9vjvCPSscvo1xGN61nZuG8NGbhaTEx6\/KkwQLN1zUjEtwPvjVpAcxTEaHgnDhfcP08vHnNT2hN07NBY9kheSd3HIQ+M8tqqEeWiHOtnb3sjHZuFnnYE\/yjNKbjj\/AHMX1Ars7Fa8Fv8A7QkrvldJBWlDPji7sicuRqbztDBc2YhhDagc5O1T5XkwljcURW7N3wJtfDLVuvdr+ldGBVjj\/Ayd9uTWrAT3WN6lsDE9oRq4rCOorKfZcehtAMRD2rQkquJFijd5WCooySegpP8AI0r0YLiXEm4pebErbRn7tPP+o15+bK8jpdHqYcKxq32G2hxp\/F51lRbZorNQ65A3HpTogBvYwZ2wpyQVI5jGDWmDWVE5leJ2UX6utvCqtyUbV25ezxb2xdCrtL4ya55peikNFUAqQx9qzdIdDKN27vIrSLRIHfXzQ4I6VtGKZLBE4kZB42YUPHQWQueIADnmuacQsAfiITmTvWUYWxlX2zPXY10Rg0KyP23usnJwN6mUfgdlZ4m8nwbGolj+R2RF8zOFJyKSx1sZfqYpnmK3g6JZRc3xiGcEDrircExJ7KrfjBJVAdiedYTxNFWPre9BjB5msPphZyW73zvVKNJiGVldju8nrWcuykwcEON8YrsVeziA5sasDlRfwL+Sl4VJO1T2URiswZNWMY5CmkgLbiPu1waAsXzsANgM0NjQMulyc5232qbG2Eq3djw5IqbbdiBp55AcrzNWmPsZcHdn0ltz54rKWWSNVBGkihVlydqSkNxKZ8IRyrRbM2iSy4XbOKrsgwPahtfEm3860iejgX2m24dtaRf5R+ldq6J9mS7eH76IelY5e0jXHsyYwCMkVmvg1GHD42juF7xWTIyNSkfrTqg7Q7ZcjPSlISBJ+tQUJp1xKc0xsiKpCNz2NjP\/AA8EDmxoijOb2ek9mLbQHkYb4xmunGqVmEnZlu3ErrxDGpioGMCvO83ckgMk1zIXARiPOudQVbFYfDKyxnfOBWU0Fnt3Z7I4NaE\/\/SX9K9vCqgv4GW8Q1lMpgn1q2AllMp+JRUgJbzh6y3KysPEKlq3ZSdF2jSgFUIwPbTjOq4PDrdvCu8rDqegrk8jJ\/wBiO7xMX\/exHaHqRXMonVOQ1tpPGM7USEjVcPlxCM5pJiaBbp1a\/QAkMQc\/Q1ph\/wARE5v8JgvE5SWQDp1rvyLZ4SFkc6mQjOHFYTSRogwyFiM1jJehsa2zZjAzVRVEMX8VjUoc861TJM8co432rZNUB9dXCpHkYrDIrEL5py3i233FTjiaJUQil1EYO9byaSEy6VWcZHTpWSokoWPUQeQzVPekMZRQr+E561L\/ACFhmtQqjyrN2h9iviTKQ2kfKrixELez2jZQT12rPkytDy2XCeMEfKs3foGGRRI4xUtEhCWwQdR7VNWMrBGnblXT+TkOqo8v71LA+WNdzRYEmdYxsRmqAX3twNLHO3l50x0Ibm6UyYPPzo4lpUdtny+wPvUMQxSN3xtUokl9kDfFzoY0xrw+JYsE7HpUOJrGQ1NwiL6+lJIqxVfXoycVrFMl7BResoGMgVolaIMlxaTvL92J5mrSqz0cP7T0GwH\/ACsf+UfpXb6MjJdtlMl7Ci7s2APc1hkVtGuP2OLe2i4KgtbEBbgf41zga2bqAegHkKw8jyHjfDH\/AFZ1YcKmuczksvEEbVHeXRzzDPq\/I1zLPlW+TOj6WN6cUByz6mP221Rl6ywL3bj3Hwn6VrHyL\/ev+SH40f8AsdAd1aFommtXE8A5so3X\/MvMfpWqSkrg7MJJxdSRmpd5jmhAdC+lUI9M7BW2vg8LY5k\/rWuNXEwm9npPDoe7tSB1FdC0jH2YHtqNV+3mK8ryv3jZk4lCncb5rnbEGaS4wFOMVm67A9x4KMcKtlIxiNcfSvcx\/sRRdOd8dKpgLZ13NSABOm9IZnO1nFF4TwqSUEd8w0xr6+dZ5J8I2aYsbySo8fhLTTtI7EsxJJ864Um9nqtqKpDiE6QP3qzPsacNUySDHLrtWMmzWqRpJXEVurDYVMtIlK2Lra4abiWV30RtvWvibymfl\/biZXxQMkmCeVd+T9x4cTPS6zc\/d86m17KQ7t4XVAzE5x1rCbsZKS7eAHeskIX3V5LO3xbe9WpUKgOQPgajvTWRoKBZoJSmB71X1LEBTpKuxHhHWqjJFp0XWQzsRjyq3slhTlQmG\/KpSYvyfWzKWIztWnGtkvZN5jGcgED1pSQkwWfiDBsHpUfTstEYrhLmQFwB0xS48dAajhUSOo5elc8tFoayQoq5NRuxNFEUkayZotk1QxWSNkG4rJyoaQn1qF3NdhyHUmXUN9sUUBTcXaKnP60NAJ7niSq2Q\/yzQuylFsWXHFFfUoarjE0UAeFjMx5GqaBqh\/w+AADp51nVozbHMSgcuVS1RJ8xxvgYqdlA094sbYPMVQ0CS8VGMaqfHZZ2KX7QQfzptUgRc1uWA0g5qeQzL8QGLxuu9ax2jux\/tPRbIYtk9hXYZmU7UuI+N2bE7LIh\/MVlN1JM0xrTHQHeXTSMMFiST65rzctubbPThqJdcxFRkDNRQXYlu3x8OVx\/MMigpCw3HdyiRHMUq8nTl\/2pxbi7TLaUlTKbi3ivzrgVIbs80GySf5fI+nKuqGRT09P\/AHOTJhcNroWlGRyrqVZTghhgg1ru6Me1o9f\/AIdQ\/wD9vWpIG4P6104l9pzTf3M3cY0wVr6MvZ5t2vDPxCQLuDXjeY6yDZnhasrA7nzrm56BBSkJGcc+makPZ7fw8EWEIPRF\/Svfj+1FH0tAAE1AANxtmpA8Q7f8aHE+NtFC+YIPAuORNcmWXKX8Ho+PDhG\/kWWWFXPWlFGrYWkoJAzvSlouCs0XBQpYdPesGmzRqkEcd4ikYWMNudqznvQ4QfZXwZWZJJs\/hx57ZFdPiL7\/AOhy+c\/sou4u5+0EEcq7MqqR4cWJ4sNcgkdayekUaK3bMRBxWTGLr+Ikkjf2rPVgArFoPw02yb2fZQnG21RdASwhwcVSZIFdhNRG2DVReykytURQCMVrG\/QmDy88jz2FbIVledCk1doBfdTlgRqp6YJUVhTJvvmjjQ7J20fdvuSOopSj7FZruC3IjIVzvj2zXn5O7NExpdXZ7rOwNZxexszrcSVbgh261uoNohh0fEYlAIc1jKLDoIuEYE88V01s5QN3aIczQJCq\/nY9TjHKhPZaQkmd5SdsdKtfJoigQvnJzV8kWgvh6vG4z0O9S5IUjRWc\/iAJ28qhy9mLQ6SZe7\/es3IEime5JGF2rO7KoU3RLvyzvzq4utjSOW9gWIJ671LyM0pDy0gWJRkelLnZIfFoI23qokswvETqv25HxfvWsFo9DH+09Ds9rdfau4zMT223vwOuBisMvZtj6G3C7pHt4ZSSS4GQfPkfzrhzJKVnfidxoZzTd6pFZ6eijN8TLIxwG+VI0QlllJJzzq1voCj7SVODyo4lJjGG4h4hpivJNE2MJcfoH8x68xW+PJ6n\/mcuXDX3QPY+wlq1vwC1jkA1KuD1616ONVFI8yf7jVEYiIq30QuzAdp1UcQJFeN5kf7wJCKSVRnHOuTiIBuJApXzJo4tbGme8WJ1WMJON0HL2r349IshKeeKAAZaQGW7b8QPD+CTuhAkkBRTnG9D0rKirZ4EqsbltZyxOc+dcnCmelGWhrHjSM5wD9aqg7eg6zRS4DbYrObo0ghzJeQ2Nt4WyfKudv4N4RbexLAZLuZ7iYEqOQ86zOhr0PuzcpuJnjU7Ig5erV1+IvvZ5fn6iNuMW7GXNbZZfeeItGdKtHcjGfep5Foe2utkwRWcmIt+zsTnBrCTAou4NKE9agDK8S71CWQ4Ga1grWxaBYuIOgwTnHSreP4AKt1lu2zp+dJPj2FB62DrjX0rojL2JombMMMYolOhIEvbJhkqNv1pLJYPQjksm73DDrWymkNDK24ecAnGKHmQqLZ7FVGFFQ8pNFtrb6CDnOK5pzvsot4g7pCcE1EUrsdsyNzKROdRwehruxtLQy6C50jdsH3rOaTCjeXDEjV0NJo5BY+CSDmoeikC3EG2+aEMHSx1AtjbzqWyrLouHADLA5\/Wp5By0VS2mh\/CMetPk\/Ycg2xtznfFNMQwY6E35CmyRReXmJQFOKhxs0ii20AeRevrQ4mi0P440WPpmsuNMTZXPKqpscH0ppCB47g9DWq0FGXud70\/5\/3reL9nfBfaejWv+AvtXYYmI7Zf+5fKufJ+43xdAvCbjTbvGxI0NrHz51zZo8o\/wdmB1Kvkci+1SDDbVx2dPEvukjuIdWAaolaMnxFdDsBtVxVlitnJ2Iz7VolZn0RaVoznce9JxaKjJPs3vYPtw\/CmWC8LSWh2I5lfUVtgzOGn0c3keOp7XZ7PZ8RteIWYms5klRhtpNejakrR5ji4umecdrbh24rIkKs7LzAGa8zyMbnkpAxZa8N4veyFYbC5UDmzoVH1NC8ScnpEDSLsXxW4lBn7mJBuSXyRvyrReBNvbBaZ6vDeW8FsiO4AUYHWvQWOi+QDfcatYOSu+rkeho4JdhbZmOO9qlgjAjVcny51Mml0XGNnmvbzjtzxaKAqxKJuUG2axlPkjeMFEycSF3U75zWDZumMHLxp5HFV6NItXs7HN3GDIxZj05CspQrs6oSvSOwTyXtyE5qOeDyrF6NaQ04ncw2sccCsAcdNzWe2JSpWzR9jeGizgNyZFle5ODpzgCtsNxkji8lqcWNeIyLq8RFaZf3HhIQEI91jpWb6LHVviOPapexNnJLtVyKOAWCXFyrLms3GgMxxVg5Na40L2IGBEwB3BP0rrcftBM2HAI0EQzjNcE9MtMaXEqxqOXKtIvQMChnUsQpHOlOfySEyR6kJAztWHOnoGKLqERkNjka2jkvRNUCfaQnX0xWq2UkXwTJNzYVm20KgwRoFBXY1k3YCnilwUBAGa2grEZ10719Tc66o6QW0VNEUbI3HrU6KTNc88rEAHao7Obor1MviyaTKJrKGADUkIsjlXcE0pIGEiRcZGc0uIimU6vKk0NHYiVznnVRfoGRuJW08s58q1aEgNrXWdRx51FlxdBnD4cNjOwpqPIuxtI6JHjUM1osSJsUXJLvhDzrOUeI0y\/BEQ9qzLEE\/\/rjjO7\/vW8ejth+09Ft\/8Fa6zIw\/a\/fibVz5f3G+LoUWUvcXKPtjOGz5HY1HRqG3iNAToOpTuuK4pR4to9CE+Sslw7jCAd1LsfKpiU4X0B8VdZMspH1rSP4JbpGfkkQMfEufcVtFezCTBJbtk2H0ztQ7XRN\/II\/ETHybHsani0y+Q57O9rbzh12j287Lk777fMVvBtO0YZUn2e4cI7ZW91aQTtpEjjfIBIPvXWs2jkeEax9p0mDd1ctqHIHBFUs9kPC0EDi\/2lMyMwPkDg1pyvsjjQtuOKxxl4jJl\/iVnochpGf4l2piaNkfSCGwy+R86xeQ0jCzMXnG47sMHOGG2c71m5\/Jqo10KZJDjbEgPUVm\/wAGi\/JyIBTkdakdhvd6sHO+NvT1qkxWKr2B4vvGA35AfvScfk6ISXou4fcNa4d\/LJxsK58sWdEJJoDadrm9aR84LY9hWTXFUacb2bvsbf6LsWZfKEgqD0NaY7bo5c6SVjniKt3hI5b9a1yPdngoTRAifJGd6i0yhg02lMDbaiiWLppJNecU11Q0C3Vy5TY70pQGLJXZyc4NKNIGgFkUSZNdHK0QNrO9MOAu+3PNcs42WpEOJ8Qd0JXfHlShD0Mhwu8RpvAzct9VVmgvQro1ttcKY+eRXC47ExZxNw5YLitYiE\/2N5FJPWtlKirRKKIRkg7Gm3YFjz4GnUKhoVAN2C6kE52rSA6FgiKyYzvXQpaE0EMqhQGAzUCQ71LjlSUTnIKDK+kA49qqMLYWfTR90K2WKikK2uSpORmplCh1ZZb3rFgDy96ngJxGsBL7nfPIVlJUFWGIjHbG1OAEZIgCM4rZv0Kj6XSF2rBgBmcQnIPOtcb2UkWfahJGVxlieeeQrqi1QMKtLcMMtvXJl2Uiy4j0jpisUirM3Nvfj\/OP1raPR3R\/aeiQj7oV2GRhe1u\/E2rnyfuN8XQlUVmalnFLh7e0tJckxsSp9CDWGZLs6vHl6KLu2W7gE9udMnUCsuzqTp7M\/d3syKY5SdqqKsznIST3IJJ1P\/8AEgV0xic85Udgl7xMGfB8pFx\/91WoqjJy2cmglBGtCBzHUH5iji49oOafRclvltcYLEDOBzIquNoz5fI64ZeTIFRXOg8s+dAWazhnE3ijOWwCRkZ5UfkOxwnG5EfJkyOYINXbslxSL5+I\/aoI1lbOds+VaRl6Zm409Gc4jwySaV9L6mXJxnnQ0noLdCUW08QAkTY8j5+lS1RSYVYBlymSM7gHfFZtGiY0gTVGC\/MHFKgsOtlyc8ydqEBOa3WRGGOh3IquwTFd\/ZsEPdrqOnKjzP8ApUyiaQmJbtu4ZYl3ZfiYVzyx7OyOW4mh7ALJc9oLcLkqpLsfIAVeOO9HL5M6g7PTLmIE1lKWzx6Es8ISXI86yUtgVycuVbJ2KgGdjzFapIYrvNQOd8elOXQXsEVdQ1ZO1Y2JgV2zE+D51akLRZw9WcYYZIqJumNh8sHmNqmwT+SFtAI5CVXbpSk77HdhxujFH4c\/SsqtgCrxHUTkZpqAnsNtJwyYxTkmgTB7w6ck1UJWFCSSQiUHoNsVu42hh1u3fZHSs3ofRXeW4G42PmKuLsYveXxaWG461pxJod28wKg+dUoezChlbMgXlg4reEaJBb6TUdPStqvsaEd4pZtK74rFtGqRG0tWWQM+c+VZSY3EfWj6cBRmsJOzNqhh35jTPn0qOmTSIRSfaJQFHXetIty0AzXh6FR1NdCxKhoEuuFA523rKcePRa0LfsZikGCee9ZxmNjKFygAzWzjoR27nTuvWocQ7MuDrvkPm4\/WhI9CP7T0aL\/DFdlmRhO1f\/ub1y5P3G+LoUAVHo1oZwwwXvDms7oeBicMOanzFYZUbYnpmT4jctwK8a2ilM6rzLDHyqFV6OhSbRnuM3qTvrUbHnW2OFsiTpCeS6WNNQBI9K6VE55SPkvEBXc5IzvsKaj7Jsd8Kve7bCqrRMN4zup+X71NuL0TJWNAYZCPsuF1f9Inr\/SfP0O9UmpdEO12BtcNr\/lkQ4ORj61DKQxtXZRKutvENQ\/f9apL4BsY2yyNju8\/\/LpVKhNj2xVkhYDBfnvWiM2yE948bq4csUOCfQ0mNF0jxSjJJwTnGMij0CQP9ijILxE86hmisvjQ6EAzk9aXqg9hcS6ccqTXoYfCgPpmhMRC5tiRldmGwzTsZmeOcL2Bt4yTks5AyamSvo0jOuzVfw7tfsVg1wygGdyuSNwFH9zVYo0mzm8mV6NK90GY4IOK4pq2cgveUSTEczWCWxUVXCkYK5NbxYilLaSU7g1o5UM+m4ZlPFms55BMhHw1QMY\/KuZ5BUA3\/DlAOFGauM\/kTQHbW3ckYGDmrbvsEHlA4GrFRfwOiapHyyAaG2IrmhBBGB9KV7sPQrmsijhh9K15DQXaZGFIAIqZWOgie21pudzUxdMBPd2BTOcYrphILKrSNoW35U50xllxqUZOCvpRChWLVh7xyQM1vJohslwy6Rzhmxit18CkqHaXkcce7Va0RQumvu8n0R0O3opIKtbYPuxyayZZbcRBMEDArFpisqW5ETVnSb0JkjeaxscGqWN+yGg3h0+ls5AzVwXFho0FrOWXmK35oKLmkVzjOcVx5sqei0qArpF5gVlF2MS3s7R7DnXVF2iQaN5JjvkD1rOUkil2CW+97H5d4P1qkrZ3rUT0ZP8ADFdbMjCdp9+KSe9cuT9x0Y+hUKg0GdnE7WMzxrl4zqH0pOPJUOMuLPOOJyl5pTMS0mTkmufjTs6lIz96wLacn03rrxxrZnkYNHHpBRs4blWrZzlos2JUZJXHzpOasGg+xVokCnmp2NZylYJUqCGkIyBuD0IzUp0Ohpasl3GI5ziYrhWbcj0J6j338ieVdCd6Zk\/t2hhaL3DgSLkgYBB50JUNOx5AY4vBqO4BBOwPrT0hXZOe67t8Etttt1piALiXKtJHsSM4J\/aixq0fWV6GjbwjCnl1HrS9j9D7hWJreVVPiHiHmaHQrots5leYpJ4WHQ0IbbqwuVlhk0gjelIIuwyz8WOX1pJFN0MntSAupeflyNDjQlKykWIkbSU+KkgZr+EcAA7LXUNuh+5+\/i6nP4lP0rpjFKNHLlbfZiZWKu2WNefPbMvRXZTFpjvyrDjsY1UaiMCqJegqE6TyFTIVn11OgXpWM0xAizp54rBooGvHRxjIrSJItmIAPI71pQA8twAB0NCQyv7SBudzVBROO6DNjrSaa7At1qW35+tFWIqSQJN0I9KbstbGCMHVTWSsQBfgYJJ2rog9EsBWNpPENtqpvY7omtszDxMTSsQTBZrGOWc03KxaPPbWcxsa9RGj6HNlHLNu2or5U20tmbD4LUi4yBjFZ82ybG8OEB23pLYmwbiUjBOtZtOxoz8ksivzNNR+Cy6O5fG6Yq1ohoMs5HLAnI9axyP4AdwXTovxVwzlL0UgmK80jnvUbGTe6yuSdq2x66EL7hxI21dPSJLIlxE22+DXPLbLQts1\/wCehH\/7g\/Wt12jvX7T0VPgFdhiYTtL\/AO6Se9cmT9x0YuhYoqDQ1HZO3aYOirq1HGK1xK2Z5HR5z\/FDs7cdnuOyrJgwyeNGXlv0pZcXCRphy8kYGZtTcyDVKi27LIJVICOAd9h602iLGKBe7B\/2KxYzvL50r9AfKmttgfpTW+hWOLJNRRieW53wa6I\/kzZp4ohdW4DRqrjfVjmf2rXtGT0Kb67eIRRMA2jcY8jzxWbZaGrsk1qCpBYY3zSsdCaZ5I3K\/h50N0UD2U\/dyuoI0n15A+VLkTZp+BXHdxqDjwHfO2xobG9kuKS91dxyxnY9c4+VJscV6Jy38bAyuQAKcpCUaB17Z29k2B3hwceFc1Km70htI1fB+2lrcKizxMI3AOwyceeK1U2tNE\/TtXFj214rZM6ssmtCc+Hp7jpSbSdj4tqmehcDUSWuYmUxXMbRMeeCQcbVvHas5pqtM8zvrYiSQHmpI2rzJPbMkgGwtmMzHON6i1Yx1ECg5UmQ9lNxMRyFCAT3kkrtzIWiS0B223G7GuZoRZMoAxmmuwF1064xnGOdaLehUK558tgNWiiUgbvWDjJyKfH2VRersGyp\/Kk1Yi9ZJJTpzU1xCgy3jCnc6mpehh+hu7yBWTasdAM6sxwTvWkZElZJjj35+laaaIorW9wQGFLjQMPguA6eL5Una6GYex4frfLjYV6ikOTNLZRrGukfSnJ6MmWsVRieXlWXQgeWcjYU0hlLFpmABzS0NMJj4emMsAaHKkDOfYFZ8AH5Vk5UTZY1uYV8IGfKs7sYM0joSWBFZzjZaKTfFm0gZq4YgDLcSSjLZxW0cVCbClQZ3NGRehIKWVVTw+VcjuzWIts9+JQesgrph2jtf7T0BfgFdfRiYPtFvxOT3rkyfuZ04+gS1tpLiVY4ULuxAAFCi5OkU5KKtnqvZXhf\/l\/h8RvCBdzsBoBBxvXdih9NU+zknLm7MH\/F7TxHj09m4yDGdIB5MKjMrm0Xi1Gzwm+4fLDI4Y4x0Nc\/LizpTs5w+IKMsxPoVqXKwSoOJC7LjFR3tjPs8qV0xhtj8WfEAf5etaQohj+3GVAU7\/1j966E9GbJ3F1NBju8LgbYIpOVCqzO8TvmadXK\/iyR5edYvJZaiEwcSZFxnbOTvUKbHxosmvEkUkMcsQedVzHQpvZmjuw4Hh5EDqKfJ3sVGw4LIXgXIHiXSTz+tVd7QqLb8NIEj\/EGBzSaBdmS7RcTaIT92zGGI8h1NEYuUqsic0Mey9yivDdrFHNH+OGRcpIp5qR6jPtzrbE3CVoyn9yL+KcRgsOK\/ZrIyfZFnLW3efGqn8JPXnj1xVZpKrXpl+PyumbywgUqkyLpMm7D5VlJbNU2enfw+vTqlsHyykFl8wcdK1xNrRjlVqzPynXNIDkkk8687IqkzmRXbQAE4rFPYNl0oZdqZJUEBGSN6dsAO+iAG3M9KJOkACpEec\/SsxAl1eqAcnA9apIEJJrzU5UEEVqoeykitImlJJ2FaaH0EJZlmBAOKlyGEPZlQN8elRYrKQjJJpzvQ\/kB5wyBXRdY3rnnKhjOS30p4flWXKxAptBzJ3NUnQAl5BojOMVrGTFQilttc2TnPSujloSC1cxqAQOVQ18BQOsPdrsMCutNozKZphCCzEitVKxUAvfNK+AcCnxLSokA7776aG0kIugmMT42rNux1Y0S8UJsRUMloMtZVJGevlWUmTQS4Ryayk6KQuv4QV2G3lWcZNsvpAEFiC+o16GF2S2NYgqppA6V10iGVTRv3mV5Vz5JJFI4qtoOQeVcV7NI9lXDd+JW+3\/UFbxW0dz\/AGnoCDIAz0rrMRI3Zm64nxN3AAiLdcg1n9FykaLJxVGw4Z2a4d2ahN5NiW7\/AAljkJ8q6YY44lfsylKU3RmuL9o5JOJRTBhoik1cj+tSpNysrikqMtdzrxHtDcXrNlYoncY335fvS7k5AtRo804taSXV4xCg6mJrlkm2dMaoWXCLbfdAgkc96zat6ZdlKb9c58qTdATD6TkbEUl3oEG2TjGrJUDritF82S96JXXG44gUikZiOYBq7dE6F7ccDEiRGxUuLYconBcw3fhD+IeexqHBrbK5J9Em8I571NDK2kOSKErGTaXvBG3N1O+RzFWmyXRuOyuZLcxkgFCcZ6jyzWl6on8lvaZjZQzTJnBUY\/pJqqJvVGIaBZ0kDHMUgww\/ekrTtIy1VML4Pp4faRxFjttqOwrVNdkpA7P\/AMX7SAw7wxHc9D\/vFTJ26NsapWes8EnXVFCWGoDGOtS2VTo33ZAaO1GTyC+WMbVrj\/eZT\/aLZwTd3DKcoXP0zXFl3Js5V1RK1Yqxx1rkq2BdI2+9VQih2AJxToOgS8ww2NRIKAHtyy+dZ2goTcUsHkBGT6YraEwBeH8Icn7zNavLRaNLa8KCxgMMisZTG0cmt1gzyqVJskXyuS2AMitFRJT3LM4bpTb0A4sgqEYblXPJFB09woXnvyrOnYMBa7AYdaviAHf3KspA55rSKAAjkVic7ECtVaEyq4DNjAzVIRY0i6Mda6eJnQsvonl2UVotDB7LhcrSgnlnyq7bQ2x\/9gEUQJFc8k72TYouly\/hAzQikDJFLO2lEOOW9aNatho0NhbOgAJIIFcs2LsOWIqc7k1jLaoEduEGgZGTisoxZQvB0uQdt+VdeKXElqw63Ree1dEsroEthDRKeZ+lckpNjINEFikznlikuxx7AOFwF+KQd2QcPnHWurGuTR3N\/aer8L4Ye6R5FIY8s16EYGHIbTNFwmy14Tvm254qv2on9zPPe0vHXlVg7ghjtpG31FZSkaxR5xxziQYFI3DHq2eXyrJv0aL5KOxEzXd5xCFmz93y8q0x7siemU9pFSyRtLLqORWOR8UaQ2YOQmSUsTvnbNc\/8mxdEEQHIUkny5UuwB7yTIOG50IbYqu5pu6J1Np9TXRCKfZlKTXRNAgXGcbc8b1LWybAEd\/t7KT4WHKtWkoWZp7oJu00IrrkMBkehqYj\/JbbX7NjWdR\/Wplj9I1UrCpG1aWG1ZJV2UTgbLKM5PTNCXyHZ6B2WIiCB9s4NbRi6IbDe09t9rge17wDvFwPfpWiVuhJ6swkVld6cW00Tuux8W1FCcNk\/wDgV7dEC5nRU6iMZ\/M0rEoo0HCILSwhEdsg1+fP61DkaKNmu7LQM12GIOnmSaiO2VLo9H7Hp\/zd7MCF0wsQSdq3x+2c+V\/aCXCJqcx\/Dk4rhnK7aOYqjGk+dYLbH2VTyDJA51VEkERiN96Yj6eIhQcVjkdFA5cKpDDFYr5ArEQkPpVKQfyEwWoj3O4ocgTCzJGqjHlU27LsU36d6SFzWkRdgBgKdcmtUDRU8oXPnRQqIwyu7ZA9amUULoJZ2dQCDtWdUUVOGXfO9VQhdxFiF2A9K3ggsHgl2GrnV8aF7G0WgIDjOfOs2rFq9gNpEGGW3FejGOjJsJ0RhsbVDWxhMTKvLFaRRL2cuJx3WDSlEaF0MPfXGw8OazhBtjbpD6w4eiAEqM1u1SM7sNaFFOVxXn5tM0RQ+AD71yctmiQDdyAcjW0UhMS3c+mU71uo6skM4e5kwSaiYwuaYpjG4qaCyKSSTv3alVztkmrx43IcVs3nYXsfNHLFf8Q0GMeJFHPPrnpXpYcXHbOiU70jY8Rv4rcMFzrHLSM5rdujOjB9rONl3wytnTy6VlN2zWKo834vfakZmzjn4m\/bFZOjVIx16+py+rI5+VZvso0\/8PYsjiFwWZU0gEkfOunEvtbMMnaRmO19wHvHw+QDtvXFmps6MekZwHbJHKo\/Bf5OhgeQ2pNUMpuEJ3xTWtgQeET2+nH1qlJxZLjYqDG3PdS5HQE10JqWzB60WrLAPFpXVjGahwldLoLXYJd3IfwpWigK2Ux5WQMSdvyqntaKWtjKO5RsAEVhwRqpWM7CE3BTuzhgdhS42JujZcNDxXKnGFO\/h5A1skQ2ajiEIu+GltP30Y1D2oSoEZ2ytUEUkkCprc6mwMEmpbLA2k0zFW1KOuOYqHIdBlhErSBtQOT1FQ2i0b3s\/EY4HcgAAYyfWrj8kSNr2dxFwbikvwt3YX6mtIaiznyiWWdgDk1w8dWYkIZSTjfHnWdbEyeAW5CqJCogB70mIpvZAowOdc81ZSFNwxI33FSl8AyUMpA8IzjlSqgYUJmVRn86VEplTS7kDnQlRRxFLA77VaYyL24YZNWpFi29gAbAJrWIiu0TWRnIIpT0IYyQhAp64rnbGL7qUICGrWHRLEl7OWOFGc10wXsRRArMcDbHStgdje2uO7TDnfFYSx7HVgi3KounfNd8DFopa8KZY8qU6HGJ9DxMsd+VTC0NxOvdtK4x8NaX6Jqg6yuViAJxVJUS0OIeIjAxgiiT0R0Wm6LnY15udM2irJNG5XIbJPSvOpp2agN1GQhyADXXibfZmzPzj73Sa7k1Qh5w22CxgjY4zWE3sdBndKWCyZGTzAqVvQHpPY3gNvbWi3M1qjuyhlkdQSv\/AGr1cUFGPRokO+J3yWsDadPhGBnGflWtlUeZ8d4+jSYE+jfcE5BrJyNEmZninELdo2Zpgc+1TJouKZiOJzwu5wNug086ybNaYolk8Q7oNn3zUN\/Av5NJ2a4gkPCb1TKA7EHQFOfrW8GuDMpx+5GQ4tIZLhmJySeVcUncjoS0AliFxvS30UVKd\/P2o\/AF2AyAjel10NA+Wic4Jx5VS32JkZhFcKRKgz54qk2tolpPQFJw+2JyCw9K0WR+iHBdsktnbx7oKObYlFIpmhUjK1SnsdFVrCFYnFVJhFfA34ZJ3dygyV355qPY3tGztZ9G8u+TkEGtbIRseGus8CyIdx8Wwp9oKaAjw94phIijSSQcDY1HEfLYHxLhutxJGNJI32yDUSXsuLLOGWLl0AUA9CayaLs3NvCYoY4AM6dz6mr9UZt3s1dqEg7MzoGyZHGrby6Vr1BnPkexBJCMee3OuWVUZdkY108uWKxBlUkhVtqdE0TjuM8qTRJJiH+LeufIikRW3WTkBWV0OrIzWyxKSDg0+xUK5LghtOfaqSSCiVuyu+WP1okMLkkVUGKSHRWtwX8P51pFDs7Iqum+1bJUJspi0xnCj51lPQkHAAoSRWBQqv4FlJ8q2g2KhRLZaThN\/LrXTFsRV3fd51ruPSto\/gaRZGneDNDGLntZCdedq3jVGLroHmheTIHSm0NSotsbU8iM0LZLY0HDy4GxpzdE2cFsYsgjaub60kyqIBjG2d62i+XZNDSznGAScmieJMpMcQTLKNI515+SCRVkZ4DpJYCog+INCt7WIOSRWvMXYVCdtI2PKndgaXsjw+K54gTI+pUIz611eNBN2NKz1C4b7JYd0FJYjmOX\/avQSNbo857WTPJbuJZQmM6UAzkVElrZSfweOcV4m63Low2zgEDb51g2zetC+W\/1qQqoz46g0uQ0L7l2ZwZHAUDpiou32OgKaRQMKCTyH\/ek\/gEWcLukgldNsyKQSDVQdaJkvYDfsO8bw4rmfbNl0AlidjgD1o\/kZIYY7fWhaF2XKPD\/AG51LasaXoi66hvQ2MoeLDeEk5p3q0JogybEdRTUgordDzq+VsmtFLrlcYzVJqxEViKgEL4ulDlsVFqeFtTYG\/Wjb0ikh4nEYXtBiVdS8\/FWl6Djsf8AZntR3D6YIu\/6MGOkGmpUwlDkjccPubfiOruOYGsBjgqfI+oqrvoydotwC5Do0bA+4JqWNMY8Lt0WUydBuAB+1TW7G2NIYpXbwRvk\/wBNCTE2jQyxTJZfZljbKDLAjYk1s4vjRhNpiqexu2izHCOW65x+u351zSwyfRkLyJIWZJY2RvJhWDg49jIlAc+VL8EnBEAPShhRXPIFHPFc+RAStLtQxBO9YNfJRdcTqV9KatAxJMDJMQgxVxZLDbe2VVy2M0mOyF0Qdhg0JBYLHGysCSSPKtEmKy15cDFaXSEcTUxJHKsckr0NE5JzGvPHnmpSHYFJdAuVU5zW0IjJxLtlvzro40BCa3MgNCdBdkray0g53NEptgwKZMsFWuuOjFtlRgESksKutENnLF0LjkBmrjGhMfW+GIwBioydCSIXsQVSa4JNWamY4nP3RKiujEwo5Y3RO2a0lkXQcTS8Md9Oo4zXBlaKQbNK2nG9cyGwQxFpPEa0UhDDhVn9qvEhRCzMcACt8MObFR6rwLhsfDoES3iAIGpm6E+tetCCgqRqlQJ2gnfS32mRhp8QCnAPpV+ho807UcSZ1bu9SA7MR\/eok7ZaR5Vxqdmd+5DDzAFYy30arRnhdgSFnDL55NYJo0dlkV4rFhGqtnzov8DoHmbWcONK88aqXrYFbFYzqJZCOnU\/LpVLQmfNMJlyAfM5rKcdlR0UFcnbl5VKd9+hssVSMfrSY0XLj1zUv4GSGBvgUuugONErHbNKw7KXjIJJGKFIZQye2a0UrQmiIjUnYU7slk+72wAc8htR2DQuutQkCyIdAJzjr8q3hX9Sbd9FtikVwpARgQcYYcqmaaNYU0PrC0kS0WW2PiLYJHSoxptt\/BeSXGkb\/sxbSW1vqbaR\/wCbrtXQlRySdsPfu2ctNMMMPEg3GfSlYzVcFERt5BHlcAZLA4HqKa6JejU9mbES3nfyy95HENZXBGw96vHFXbInLVIDNnZ3EnEriLiS\/eyairxMNPpud6JKMr2Zu6ENzZShmNrcRSN0CSaGPyP96wlH4ZmicX2oqFuWkI6a9\/oayk5VTGX4BGKyvZLKpMgYzVDFd8SGPUVnOgAVnCgLjx6s59PKpaXGqEGo0koAztWD0DYRBEoxqFSpbAsllCDArRKxAGS7kiqEEMNKcsmkmCAijGQHcU\/wUwlAVBxUMkFu2YjbrVRHZXa2JY6iDnyrpg9FDG2tSZN+VXJjHC2aCIYFZWSCNCqtuKqIzPEhRrxXb0Yi29utmA5VqtoVCmK6cXAVScE9KmcuJfE1vDpvDud8VyZM1kpIvuiShBO1cjnb0MzPEoQZPOtoSYJkLZVjYYxVsr0aHh8wGkDfPOsJRcuhDc6WAyKPpP2FlEowQBzPLFL6YWeh9heCoIFuRJl2GM4Ow+depgxqMbNIr2am8uYLSDulLM4HTfUfOulFM837T8SjiiJcuWOSdJ5fX96ltFJHkPG+Ma52xO2kHcNtmsnI0SEd3d98gZlEijbw7\/U1LkmUlRnL5xnwDHpyrJrejRWCRzlW2Yk+R5Umr2MKE2lQTnX5g8qla6Kq+wcnJJDb9TTsn+SmOZoZQCQVPPenXJUAbkMuVOxrJqiyKthtyalUwvZehBO2aXQFobA3zSZR0EHOGz6Gp6AtChxuDnzNDXsQJcLpJyGO34etVGxMo0OSCgYA779Kq\/QUXRxlQNUm\/Ok6YE3tkmXxc6UZUJqypeFywnXAQ3mD1Fa877KTobdm1kX\/ABidAOdNClUhydo39pcwvGQ2Qhxgqd\/StuRg4tPRNEglkURRtITvjHOlfwGzdcHtlS1X7vuQdgNxVr8kNm84PDHb8AuZnUs5BAIJyPWto6VmUuzHWd5cf8NkaV3bU5GHAbA+dZObStiloXXTawdogdtygKn8sj9KynO0Qg6yYgFZIwDyOMjPuORrBzp7E2QuI4y+Ae6b+rdT7HpRcW\/gTBmiYHSy+meYoa4oSAru3IztXPOQ\/wCRU9uokBAwaVv2KxnZoiKPOspJjRbOV55xUxQWDGMyEitYxoTOxQiJh+dUxF0gAzjbas\/ZYtuWCbr9KpbAqW5ZtlG1HEh\/kthRnPjG1VFAhkigIANq0WjRF8TqnvVJgy43aKuC2KVCqwKS6Vn2INWkOhBK3h9K2Ut7MRXcwd4CRzraLvoRCx4eiHUeeetLJGyrGtu4gfB5VySgLs5e34xgGsVjt2OmKLiQyHAOc1044NjWipkZVyDWzhoLCuGXUizgEHas1jUWDVmjjmllKpGjM52VQMknyxW3FMk2HA+x147rNxWQ2yAg6FwXx652X8zVR8fds0jCts3J4jBaWC21voRV8AzuSfXzrpNaoz3GuJyW4ch0U8gV2PyFO6FR5\/xG\/Viwbxux5ybZqLLowvGpxMrIsKvg4BTZR\/eol1Ra0Y+5xE5BBx004rF6NBRcxHUWB\/Y1H8gBOxjbYnbyqtS0U7osgmBI54586loYQxLLsSfY1F+hgsib7VaYmtn1vMYWAbdD+VNpSEn8h\/hfBU59KwaaKRNWOcFT8qTq9jReN9t8+QGalqvZRcsZUDVpU9ATk0hfwTUYI+N2\/SlWgJtA7jI0K31qv5D8AslrJg65QM9M4o5UKj6O3TffVt060m2FB0cbEACPAxtmmlQfyGRQlY9UrAADOwq0qA+tFUHLgDJz51ToZo+ElQwMZjydsEVSJZq+C2MssyyP4VHLbGapJmcnSNfZIS4RASM4x51qvgzbNzff8p2fEJwjBScHYj2PUVtLSoyW2efQXLNZBZUEignmMH6jn71yzm6HLSKHiiYEwyaTzCy8x7MNj88Vhaa1\/wDf1MgmENo0MCrAZXHIj0qGn7AHkcMSGbw9D5Uo9isstmK+Enb6\/wCxVt12BVf4UZG37+1cuVe0OhBcFmc6frSTT7JLI5zGuDzpNCsp7\/W+kk0IQWjhWB1Zq7Gi4TAjKik3otI6\/jGayGIuJyFThSRW0FZIHbSvqGd62caQUPIWZogRWcexpF3eEKSa0oo6ZMLlTTSAX3M0j\/DvWqjXYFCSkDxbGm0DRNwmjehnP0ByMkbcxg1pBgBzXIj51vVggCfiWThTk1m4JmiiD95JLvqzmk4JILoutciTc5q4RSE3aG1vZT3FwkcULuzEAIoyST6VclS0JKz0LgPYKXQknFEFtyOk7sB645VjHA5bmaRj8m34facN4OGazt4I3xp7xvjPsTy+VdKjGP7S1FIncXYlQCdjvkgDcD3qv5H\/AAZ\/jfGIbNcoPFg4Zvi+gzik3Q0jE3t9czSNIkcecZLy56+XpSVjMte8SnmkZSneBNsQptUNtlJJGb4n9on8OoRoPwjwmolbLVITX0MaAEqM9d8VMqBWxXMwYkBSrDbzrNloX3CnO+Tj0xQigbBDYGfar7F0WhyBz3qXGxpk2BK7sBnzqdsZEoQDjJ9aL9CqjsLPC6gZYHbSN\/pSe+g6G8ajH3hycfAp3HuelZSiNO+i2M5ysQCDmQu31NQ\/aRX8hCRgEF9yeQXmanb2Oy5WXdSFwOYHIe5607p0In3bHdBz5sRimBNLaJjtGpP4iedVQFxgAA7tFUelHGw6IPIsWdi7eRp9IFsqklmlYB9h0A2oYJB9hbGVsHJNUkNuja8B4KjMsjjGkCtIxvbMZS+DY26BAqpv5VbZBtOznCHiVLq5GAd1FbQi1tmUpekH9ppddhMx28J5Cqn0TE874FiTh7MqqV1nIU+Ft+Y8j6VyS0VLom8PXPh5g+dc8lRkfFmiQ6T6jyzSTAAmLCVtOcHcfP8A3+VX7EE2kjYww5cqO0FnbrxqVPnkelc818jADaDfPyrJOiWimWzO+c4o5CYO8JHIAnNCZNE4UdV8Q5mnZSQbawZGWNLkX0XyqvdnHOhfArEd1bmYkYrSLoRdw3hul9R396pyBbHC2gVdhU2WUSW+52zVqQwGeNgCApFWmI5BbkjlWnMXRyW0xzFLkgF9yy5wa0dN2c7FF6cnCnatIRb2NfkVzRzSEjOR5Vsky00VR8Pcvvmqr2DkO7LhU0y4giMh5bdKmhdm57L\/AML5LwrccbuvskBziJPjPzIwKtQ+S1B+z0rhnD+F8EiEPC7WGPG3eMcsfXPOr\/g1UUgfiHE1jG2RKOshAC+n77UrGJ7rin4GlXUN9bJ8PrvQMR8b4y0ulVnZtuibGhsEhHe8QPegLpVwMtlP2oYIUXdy0spM0jPEPwBcA\/QfpS97K9CPiM0j5RUUIPwg4AqW7GkJpY20HBEW2edZvSLTEt5GjH7sFj\/M+wrNu+h7XYnuUAcaGyeuBSe+iugV8bAk7dM5qbGVEDoCPUU7+Q6IFSp3OKpb0BLYD98UNgEwxMcE+AEdf1qKCyxmWHAt+oOXbmf7Cl\/AHYYG3csVGfbNS9lBUF0WOlRsNtR5UnEAxAGGEJC8iw5sfIVm18AXqoXAxjyXy9TS6HYVCd9jlR+dOwGEQTGGAx1qkxUFpBFKo3xmqsNk14QpK93pOTvR2K6JtwVu8BxlfTekkPkPOEcKSNg7DGfOrj+SZSNPaoBhE2HI1d30Q0bPsvwxJJkYpqwetb4oGU2bSbKkL0A2xyrZmSEHaVscMmPXSazn0VE847LPiwnRhhC5OK5MnWxy6HQKumkHxc1PnWPemZFBjJ2POosCBtxpUnGdxTu0iHssit9x+lWlaFZKeNAOQqJQoOQBOVXlg1g0VZWzhlwSDWbv0FFEioNxS7A5GwYgNnFNIYbGY9OnYmkxPZ9KiketJSCgbuAzagTn9K1T9AFRJp5bU07GWGXAwOY61cYWMGedc4Jq+NDKtm5kUxMIi0qpzyqX2IDu5QGGMUIpGFe98G78uVdaj8GNFH2gMcnlXVFUqChjZhNJJwSa0SJ6HHAeAXnGb1Y7aCTQ22sLt8s06HGPI9b7M9muF9moGd9d1xAbMx6ew5D3oVI2jCgi84i95IykqqgYwG2AoNBDd8T0gxwxtIEGzEHT8sUrsdCSTiAWAvO8ClDyRST7UrGLLu\/e6bw28rIN9T7D6UXYCfiU4kcy3lzsnwo2QKTrtsavpGevL+OJS7PueShtTH2HIUrrsdWIJuLXcjd3aRtFGTgszfXNZcpM0UUtspa5mRiryfJdv1ovdCoruZ2WMKrkZ8yTmpmykLSxbLO2SfTYVG12OrYHM6hMKoGeW9FgkByZOwAHr51Mex9FeVY9fem\/wM+KZJxgdM0RYUSTKkCJQXPJ2GT7+lXyS0iaPmZj4UZmJO5PNjU2NIvgiCkO27Hy3+lQ2CJu+onvNwDjSDkfOl+GN\/JZCjytjYAZJx0FTIYXqFuQIsa8bDotLVh2RjmkXIcZ9RUv0h0MbeaMKpY4weRHWk2Og+NwVHiHnvTQ+w23U76WoQDqyTkS2McxVIljS3UKuM5IqhdjCHU+NsCjbJdIc8Mh1SDbO9awiRJnp3B4DDw5WCpgDOccvpXbFUjlfYWG1DJBGfWkAj7Uf+2TDzBrOfRUTzzgTAcNYr5muXL+0cv2hKTKDpJ26Vio2ZBEbmRdXUHDf3oatWDIPOFwPU1KRLPlvADzya3USGiu8uD3edQ9qiQjP3l041YbasWrLRRa3bsSBnFZSihhaz+DLHNKMaY2Ui4Pekcx0q2hFsd1obdvaokgCheIQMtWajQyyKcNyNaJAGoNeCT9KdAclTKnetYsBVcxvr25A1sqopE7dsNhxUyExkgBXIFYt30IXXkZ18sinEZ5dOCo2r1OAuwUSvGc5yKcVWgo3HYjs9xPtNKGtYZBaKRrlwNPtnzrVJsnjZ75wbhdr2c4WsdkjNIww8jnLMffoKvo0jHQHxHiD2skoZoEBGTud\/QedDdFJGYv+KsUCvJPobOkYC5z5VF+ihFd3zupVZkKDfSHJI9zyFK2MXXV9P8AZcwx26nO7Dxftik7rQ0tim4up2jDTSPI43A5D2wKQ9XsWXFw8hx92HXc48X1NJMekKLoqFLR6nb+dsb+gpfwMTzSkbKmk533x9ai\/gpFCtpRyrBmb8TdBU9Jh2L7iXWSUJY8snrWT30a9EFZ1UmRiBj4SdhQtE1ZWZUKnbUB1PKmmhUweTSSCMmlZWikjJ8hQmB8MkDA39edNu+wLipA0LkseZNT0OiccOlCxbCjm3mfIU+XsmvgreUjZc49ev8ApR2FHyeLQiruTtgdaUqSKT9DJNNtFoB1EbsfM1HYIHV8yHJOc5pP8jDLRRJINXLmc0m\/QwhF1y7bIDgCpfY0MoYVYZbcHlVUAbb2pXlyPyp1XQX8jyygIxqJOepNOibHMKaQoA3piGlqmRvzqlvshmh4NFqmQAZ3reC2ZSZ6Tcqltw6AqWDEAEV1PowRGPdBtipAQdr208Ll\/wAp\/Ss8nRUTzngPh4Tz5sawmvtHJ6OtnVtWcdGQztm55GxG9TasRRcKRz6VNUxAathsjlWsQZGRS586znEzsC4hB4ccqzLQNaw6WAycedZN29lBEkbKvUihNADKTrJUZPSrTok5IjaRkUqTArYMBjG\/vTSQwvhZYMASdPTNJ0ilsfoxCbc6gKK5JGPM71omIHlfzFaroaOR4WTce4NJoGMonQjntWLED3JXPnREDyu9XoBua9liizVdguwE3aC5EnEYprexQandvCG8gOtOML7K\/g94tUtODcKitLCPTbJ4QB+I\/KtHpFJCrjnHJAoEJAB8JYqfD67UpMaRmuI8VMEaiGNJpjsHcAE\/uKlv4KoQ8TnuQVMiRKW+LS5yPQdaHoBRdzufuoBCzHrnOk+tS+6RSS9i+SxnP\/qb5CP5IRn6nOBU18sd30Q7u3jQYjKr0csST606AWXd7bRRuBht+eQT9Klz0VxdiWW5M58CESEYBfc\/6VPK0VXyLrhGiXxyZ+dZsfYtuJGk+AAR+tS7e0UtaByGXxO3Llipb+RkTqcjSAPU70v5CjjL4dyo+dP2mgRWcdOZ50r+AI6d8ty6Ci36GdjBJLDHPAou+hUXJpXwgeHGT5mkOkSYtIwPIDZfSk5WOvRFotXMn50m17AnbxlFaYjGDge\/pT7FW6onIwGFz68t6KroZ1ANJON+YHrU6uh2GWx0xEnGWGPcVIBlts5x5UL8AxrbqNAxgHPyq0AwiXSQwJ22xQ9bD8Di0OkD86diHVthwABmqJGdvGSNquKIkzU9moc3CDHXlXRjRjNmr4vIW4hGgYroAGnO1XLshdBsX+GKCTM9uGxwmY\/0n9KzyPRcTzvs6S3BdTDfNZT3EUugrTXPejILikCKM9KQAV1Pk7Hl4TWiiAIJMsN8Votdgw2BM4zstYy2ZsqvkwueYrJoaKLVNTbgYrnkygua2DKBtijQgZrQxjYZosD42+caqObodHzWqEHGKfMRO3hRCNtxQgQwBUIAAc43qlTKBZuRNXQAesscetWrRVl+NWSTv5mqcrJBXu+4JUmk430CRH7aGPPNJQYxX2S7N3fE7lHezLREg6pThcZ58v3FetGPtkRdntpxHbR2dvEY4FGp2yefuev6Vb3\/AAapUC3HEILSBu9AeQ7RxknA9ccz7nnSvQ6Mnd8duLebCffT89vhVfQdaV0Nox3E+K3V5faGk7oj+nWc+WKi23RdJKwe5muApUTA52LSgajQ7BL2ykS2qwkTktIOeDjfzIFHoE3ZS725iB7kMR+MA7D9Kkr2AXGm4AZggj8y2r5VPfZV\/AqmigG+lpGzyAwtQWVTPMqHGiMHYKq7Ae9JyYkhbJAzAv8ACg3zn+9ZtKrKsWSsdegHLZ96E7HRTIp574PM5qLa7GU6gmCxJB2GarsXWzoBBznfpQ1QH256\/OlY6OKgZtiSDtSukFFjgL4V6bVNhSJlMDBIHmc0+kOiaqGcYzgdKXYFyqSSW9gKi1Yyy7jzoiAyF5486r4sSBCuJMtnOadhRbFz67chSqmOw5gNBxjAwNvSk9ISLIAQ4I2zz9AaSK\/kZQuc4U7cv2pp0L0NraYMuCMYG\/pV2IdW66kGDyFOtC9jWxJVwpGG54oQPaHltv4sEZrZbMWa\/sudMq6up51vjMpDzioH\/FRhgwIB2py7JXQwT\/DFUSZXtzvwuVf6T+lY5Oi4mL4VGI+AIwO2d6lr7QfRT3mX57VzOOjItY5jJBoihCu5YrK\/ln966EgRGNSd+lJhYzgcBQMjFc7ZnIpv5gBzGKiT+AQJazAPudjWEo2UOY5FZNt6xpjOFlB3FUkwRVLJ4eVNxaGCNcrnHI9aaQmz6O4B9apdiLGuVVeuKtRofYHLeliR58qtIZCGQ6\/SqaAOZToyOVSmIQcSEhfw8q6cdVsuJVAkpG2eVVJRK6Pc+F2MXDrWK3tIUVwMFiAGPv5e2a7\/AOBJJFHGeJJYWza2SJs+Jc5z6f6YobpAkYjiXFXuAzW9oTncsfCx9d+XzzUlGbuhKsOtiI3O+X5D59aT0MX99Aj4W8bvXB+Bjy\/IUv4GLbqOKNSzszNz6KB71LSKTE13cc+6ZcHfOr+1ZyZomAvLNI3iaVl6AucUtsKR9FDMVBZwoHUg4\/Palsdou+06MqZlydj4xmp5DUSE00khwDHgcv8AZqXJvoql7F1y8m+cHHrms2\/ka\/ACUfGQq6+eeVNpiKXGkfETU\/kpg7qNWWB+dNCPhsBnwg9Opp6A6GyQNs+QFTVhZdFu3i2wDsKl9j\/J0DQfXpTTsCaqCckk1LGiwKckYwDST0DDLQZYMR4U3FNfgC0x6vT160xUDSwBV5H1pVQWQihKuM7Y3OfPyo\/A\/RdqCqqrkk7nHSlYL8hcSkliD1xin2ATGCFA6Bt96KGMrVxkqBnPTzqhD7hsgLEZ9KZMkPrcagjHZga0qyXoeWWygHY\/rWsTNmn4CdM6bdfpWsTKQ84ggXjGV6gZ96cl9xK6GS7IKZJku3JI4bMR0Q\/pWOQ0iYjhUrf+XWLbZND6E+gaJgMc96zaMgwMBHk8qiIMXzSRgSZXJY7HyraNE0UwyjGM0NARe8CNiuSaFQPPcl8\/pUICiW9xIMLpXyq5pSChnaXo0\/EBWDiOi9bzW2Cc0+NAi93Dpgc6bGCSW4HXej+SWVhGXcbVPsGzsjZGPrW0RogYC2NJxTYy61g335+VQ2MbrFmPHSo6EwQ2IeTltV86QJBMfDlQfCKh5GUbjivGIrK3T7TJDC8mcDckD+kcyfWvcbrspIx3FOLwSeKytJnYfFNcHQF+ZH6Cpv4X+ZSVdmZ4nxmYRYFwskr\/AP0jnG\/5UndDpCWeD7vvbqTumYZYa9yKTikgsSzcQjs1ZbYSkNzIYEn6cqlypFVYtuTeXOhiNEf4dRJz8qiSbNFSB2trtWDykrttpODip62PRwTYzqjYsfCDqzj19KLFRHKsPG7LjpUPZV\/CPmeNQAoG45EVEnSopfkHlLAY1BTnOKztpDonHGGTfGnmf6jTVAUXDhixXJ26Cjl2x1oGAG55n2qWMGc4bffy25UxEBu2+T5gVWqF+C5MYz8IqRlqDBOFyfWkDJrGS2Tgmk9aGXaSB0FLYEol1AnmKSt7BhcQ+6ONs88VURFunHxfCOlMZ1o1ZR0PnT7QuilYyD6kHHpSSAjHFq8Q6mppjDVj8OB8R8\/Kq36AMt4yFPUDYU1pC7DreA4LLsR1oHYbbEhtvekNmkspNQUbnI6VomZDy1JGnV8PPUK1jfRmzT9n5i0+Djngj9xW0HbM5I0V9\/7x12UfpVS\/cQuhlnwCqJMf2\/OOEXB\/oNY5Oi4mHsXB7NQ\/1Gk+hPopC4QH86kzPu+KoRnanGIMU3c+SSK0URAkU7d5tmhxHRJgzN1rjy6ZNk9IBGT71iybB5cMSBTQ0dgBB3zirbTGwy0J7zxbCoe0IdQqSD\/eoHdEZEYnfO1JsVlMoZjgcqEiSyOIY8XPpVWWmSICDeixgpulSXyqlGykg0X2wOqjjYui6C9y29JqhB\/2xQByrNwYz7iXECZZJVto2kfIM0rkHHv\/ALFe5s0VCKd47p3e68W2cJsPTmaXfYwG4\/4NaBXmtoJJseFM5b3\/ANik6Q9sUcRv7a6TUIo7dQdlYFsepqXT2UtCe4SF1JtFLkZ1SsukD2FL+AuhfNPJERiR223PwgVLZSSBpL1c7hjvsW5fTrUOXwVFWVTSkjOpSOYGdvpUsoFklkc+E\/Raybb2UkdV2TxSOGPTpU2vY6JLcZOERAQNy1JsaOTTM641Zz\/KNqnl8jopdNI+E6j1osdFTEoAvU8hRaFRUYgNJkI1enl5VVhRW\/hxy38+tNCaJoceKQ+29Kx0FRR6upHlUtBZ0HS+hBluvpQgCFQkgEnJ8zQCJMBpAA8P60XrQi+D\/CBxzfOB1poGEW\/jJ6k7ZqltgXmNdJwRgbknpV6YugYou50+2aj2BfFCMZPIYycbmnxvYBLRZ3xjqRTaGE2kRB3G3SpSCxjEhUYG\/wAqKoAy3hXSxxzORtRQnYZZs0U4TGxGxoWgZpYWwijOCdq3T0ZGm7OKFmB+R9a2gZSNPcnPFBlQMKB71Uv3ELoYD4aYjHdv\/wD2i4z1QissnRUTCyr9k4LZxNjcZpLaFPSBe+wmKKMgOafYgVpFDFsjlmI86sBjw+yBGSKwyToTYfJbquDgA+1cU5WyGCzLp5Lms09k2CGIEksNya1uxoJigBXYVm2UXxQKo32NCdiYdCB51EhFjqSPSkpADHbNaLYgaSYxnd6pKyokYZHnJwcim4mlI+ltSQTtmtIgUEPGMHetaAlA7F9iOdTKKBh41lRvWVUItu76GJ83gWd15gZwp8gOtem2bC+a6NzJrbubePG0MaZkpW+xmeult2d\/uQXJ5leXlnGM+1KigIRwQAu4cjmScL9BgUugBbu+gOUtxoUHJAGTn59alyHVANzcgAFlYnmFfB+dS37KSFrzYfXKgXPINz96z12OmVzTQlgFQMfMVLaspJnCcAksFz+HrWcrRaI6ojlVDY65qbKJK8QO+nI\/D5\/Ok7D2RkuE6IAQeYzS\/Iz6LSTqckk9cUm60B82lXJUb+tGgopK5xvsKd2BXKmny500Lo5GpLZOcdBTYBisVTI3Y7AVLdAWQRaFGR4jufWjQglQAowMk00BUwKDxHep6DsshdjHt8ZOBnpVIA1VWCHAOT1pqohZeGAhbI35\/OqT0Ik0Q23ycZJqgCI49thk5G1NAXxxkvkjwDn60AFwpuCRjbYe9SAwhjGBuCR1oCxjbxDmBQkI4YtMpJ50qHY2spC2lThhmrUvRDXs2nZ4feqOpNdMDnkP3lDcUYMwDfCozzxzxTbXKhLoaD4c1RBke3ahuGPk7YrLJ0XFmG4uFSO1D7ppxmnjonL0Jrpgpwm486tr4ISBWZj0BzTQyEKFnAC9aUpUQaG0CIg6VyTdiBOIXscbYJz7Vg02yewZbpHA3qKoKLWRZDleXrTv4DoMjRRHtjNZjBbmTu98jFUrEyqO93xTcbEWm9ao4DBLm6IG5wPStYJhQsku3mfSDtXQo12WlQ\/4aiCFShYsRvnpWU3RTDHAVTWansBXcsckiuqLGga1nImII61UkJocwy6huN6jiIDSFjreVZVA6zSgn0IC8q7Ujd7BHtJXifXcd3E\/RAAxHl6D8zS3QaFcosEBVO8KqTqfWWY\/LkKFRW7AZu6fLLAhUDIOTkDzNT+RgGqEkmMqMfyruaVIdg8oaQ4LFc9OWPnUNDsFngSAEIEPm5Xf86h60irBwzgkjOnHMVP5GVmcfh0\/Pas2y6Po5UfYohcdSahpdDOyW+d9SDrsM\/Spoop8BbBJ+VKwouTSdhjbnmlQEXG53HsKa0x9kWAzsNPTnyoq+hFUyg4PPAyapOgZGMeMADb9ab+SQhR4uQzjr0pdof5CIuR22HruadUIJ04UkgDoOtOrGBTnLEDZcY386m\/gC63kCKzc9tvShaEycLl33yRzNNDGagYXB2B29TWvokLjjwFJ3PWmgLtOCBgn0FDAZ8M4fJfzCGDTt4mZjsPWuLzvNxeFieTJ\/RfJePG5ukaWDswsckEou9YRwXUxYJOehyfzr5jL\/ab6kJQWOm+nZ1R8fi07Lbns3PEss9ky3MROVjUESKM7bfi59Dn0r0\/A\/X\/HzpQyPjL8\/P8A7MZ4JR6KLSPYAjkN9utfQx6OZljw6l1DbJpNaFewrh8OCoG7Z6daVqKcpOl8jdvSNfwpntyGUDWRtn8O3OvnPM\/tTCDcPEXJ\/L6\/p8m8fDvc\/wDI5byL\/wCYoriaRiUzhm8iCDn0\/wBK8rw\/1PJHy8efyJt\/Lf5N54rxuEUbdMMlfoyPEZjO3hP\/AA2VBjNZz+CkYvjkEr8OtWHQVUF7FNiB0Ye9XRK32QQMTUsJDC0gz0rCcjPsMliZUOPKsExGV4kszXGQuR607URrZ9awMMFs+1ZOQMdWowviGaylJE0WTXCxJUoYmv7hXVNEgLN0HSt1HSlYEIBpAJ50mAWrE7VJILc28jxlgDitIyoaYFaW7CbDEgk1ry0WaezUog07VlIYZHGZiN9qxfYXRO6showorSMqCxNJYtFJkiu2ErGpBCPgb03EEhD9sIKy3crzXHMRBcgn1zzrZP5N6K7l57te8vNSDYrEAB9cUmm1sapAt7mRVydWThEQjA+Q50nsIgk9uwx3zhRz0nI+q0mMqkZwhEYVNI3J2ofQ0ASBxltwOmWxmoZSYOwc+KWQAfyxksT86h2UvwVyBSw8L456WH7Vm38FJHPCwOQQPMryqSitYU1nYMPXbFQMI7tFXUBnpy2qeuh0RDo\/hGAf6RihKw6K+57xjvgA450mrBHyxDWMnOD+dL2MnoGsgADHM0xFPdAMRg88mnXoD4IEm8yKpIRJvxH0xmlSTAJt1wrHAJqkhBEf+HgeVNL4CwKddLbDIXelVBZxScqoB2GCPU1PWgNFw7s1xK94fHc8NhW8if4hC47xT1BU4PzGa45fqfj45vFkfFr5NHilSkgy14BxJC32i0lt2XcrMNBIHPAPP35etLL+reNBL7rv4HHFJsYwcDvJwjRojRnxBjIozWX\/AO74kV97af8AAS8eSeiq64Xc2mhbqIoSfi5hvQEbV2+L52Dyv8GV\/wD3wZyg49jbsgJpL9obaJ5JJAdKqOgPP0Hqdq8\/9c8KflYY8FbT\/wBzbx8kYNqXs1xbEsEEdzC7EkymM5UYBwurGD5kjPLnXxuTxY4nx5Jtr16OxPluhxZ2d33Bk7hzEpO6kNtnnsc4rmn+n+RKH1IRtfgX1Ip02UcZtlvLZ7kD\/m0XJcDeVRzDeZA3B57EHO2Pf\/s\/+tTWReL5Du9J\/n4f\/g58+BVziJooC6Kq78sV9p5HkY\/GxPLmdRX\/AN\/\/AIcEYucqiaHhHC+4geWR4yrgBCrjUjDnlfI+4O3Wvj\/NeT9SxOc7jF9K\/wDVr3f86O+NY2ku\/Zd3gRsYKsMggdD\/AL3r5VRcJ8GdPYoguQ94xO+pjXZlp4y3GjccCuzcWIU\/FH4TnqOn+\/Svv\/7N+a\/L8JKT+6Gn\/wCP9DxPNx8Mlr2ZXt9dhIZEzuRivblXJI510U8Ak4ZxjgsUU76HTZhnBq4a0yZKwmXshw24UdxdaSBsM1dWT0Ze77OXVvIdEbOobAIHOoknQmyUFjPEoLROAPSueUX8ElkoJGGWs+LJFFxbozEld6xlYrImFU307Cs6sVlclzGPDyNHErsV38yupANaQgOtiwRKbvwSak55rWcElQ71scRxpoAPM+dc7WyaJoV7wKOdJokaCAd0CoFJIZR\/w0skk6L4YyAcetbQ3f4KWiyNNIAqnG9lBtrzHvWM4iGekaMk9KlKhWLLvBzvXXiY0K5B4utdBRk7m4jMmYtUp6yyLqJ+XlVWvR01rYOsyuxHdO7DkXGB9Keg2iYkdWIhjZWYYJUkE+Z9KX4QfyDyIwADzbdFzv8A3o\/gPYJJKxyowB0KkAj\/AH71DZRTr0LjKZPJnOTSt9DIMsOol31OB5VDKWyh3bfu1yDgcudZttlKiEkcoI1bnG+OQ9KTTRSIRpkgFBgeeazat7GEMyY0uwY52wOVJuxqyLW4DaiCOu3OihrZaqnRsD4fpR6FZADKAj4ydvekkP8AJJVGdgMDO9NJehHGTTjOd9yc0aD0DuPEEG5J3AHIVS2LoIZVCKFBwMZ2506EEcNtxPJo7xUdidJZSQT8uXvg1lmyrDHnLo0xY\/qOl2Ol7P3yrqAgZT4hpmBz7Vx\/\/r+MpU2U8MjOcRjkgublJkdXjIBUjcGu6GSOVcoO0YtNaZPh9rNfTxQWyF55m0KPU8z8t\/oaWbNDDB5JdIErdHqnZrhbcFhNvHcNIwYuWZcLvjIA6jI618L+o+avKyfU416PQxx4xo1MRhvYwtyupc52OCp9D0ry4ZXjmm+vYNP0URcDAiYcLmaUqxzBLgSL6A8mr1H468lc8Lv8E\/Up\/cLrnElvNbXCkDGCrDdWHLbzBrn8d5PFzxnFfcn\/APIqSUon3COGNY2EkTsUuJADcINtPkh88cz6n0r0\/wBd\/UnPL9CD+1d\/z\/6M8GOlbDY4CiqYtjvg\/X+1fPOdvZ1BVs8tuFWN2UgblTiiOacHcHQmk+x3Y30XEBouWSG8HwynZX9G\/vXc3i85VlfHJ6l8\/wA\/89mNSxbW18A8trHZzSjBjdOcZGcH09Dt+1T5\/m+Z5GSHjeX3HX8\/l\/P8rVFY4QScsfsHgkeFZHJOnIPPlXoTm4RbI42QuZjI2C6owGBjLH6Dy9ccq87JBTkpzaX+rNYvihbNCq29wqvKrpHrBXwud\/Tl1\/v0qvqpNKH+ppbfZrODXEkF3pQD78BfTfdf1\/Ou\/wDs55UvD8\/6Eup6\/r2mcXl41kxcvaLOIdjrzi12JZXCrn4SK\/RJYnJ3Z5Kmki+3\/hvCi574Iee1P6X5Cw1ewxVQFugMcsZp8H8iLl7K30enu76MhTyYE1S5r2JxTOP2f4rqwZLV08txn8qblNi4IHl7KzvICbWErjcCQZpd9ol4\/gEfsTqdme0cZ5aZAcfnUvHB9oX0wS77EgqVS2ucnbUOlL6UPgX0hJe\/w5uSpaJ5dY5Bo9qf04+mH0zN8Q\/h\/wAYiBYQd5nyBFHBAotDfgnAoIOHrFxThZWdFPiBB1euaHBNbRSElz2fvAxaK3bQTsM8hXM8RHCT6B7fgd2s4ZoZAetS8XpIX05D+K1miTHcMysORG4qeHH+ouEvZV3ckUbxmCQI5GoYODjlWkIpLaBJi+7QI7DRoAqnH4K\/kqt5W1YBqXiAMLXOF0gNq2xmoeB9oAd4bxmP3Jx71tjxSXY7RGOzmJOY2rbiwtHnUErySNjuiRuXYnb2wdqI7Ot6LHu9CaAxwTzQ7f6\/M0NhHZAyNpCoZEH0\/Xal6GwaWVFU90yNg+IBgcn1NTLXQ0CmVpCVYLg8lxn86QFc0cgUawUHPCjNJoaZUsTFQNGhfMnc\/KocUUmERukORrBI6ADak2PRF3z4u8IH9Oahp9jIKzA\/ET6YqdsqiakjkpY0mqAuVRjx+Hz3wKX8jI6NSFRqI8uVTVjIBMEqB4j+QopgXIviA8jyprb0DRwx+F\/MnIOKaXsTB+6bmu45Ek700DPiPvFXkDvjNNMTQVas8E0cqsAwbUB54pZMayxcJdMcZuL5I9J4LdQXUIORqI2B8jvXwPnYJ4Mji\/R6cvuSmumR7R8Dt+KwBCe7uUGElAzgeR8x+lV+n\/qOTxJWtxfaOeeNS7FfY3gU\/BONyXV+FKxxlYmU5DFtifkAdvWvQ\/U\/1SHlYFjw9t7sjHiads29wI5Cs8B8B2K+Rr5labizoSOJKIZAcnf8qTXJUMJaQm4SaF+7lHM4yDTxZZYXaJq9MPvJ1nlguokVeIICvfYzp8iM7EjfB5j6V6eT9VSUcmNff8\/H\/wB\/oRHF6fQHDbLCrSPIBhfEzHYjzJrx5ZJZJUttnR0ROFgKZJKylR7ZB\/8Ayp17\/BYUAmWwMdDWGyCi4jAGpdquEmBWvEHlg7qclpIsCNvNc\/CfbmPmK9GWRThFT7j0\/wAfH\/AuNbQwTVOBGoKgjd\/2FGfy+S4RIUaC4IYoEB0AN1yMFTXA8lbH2IL64X7fcaB4VjEY+uf3rqxxf07ejZR1Y2snJtYH1YYLseuQdjWflTljyY8ke0l\/ozGNO0zb2\/aLHdKxXvZVLqmd2AxqIHkCa\/WvE8yPk4YZY\/8Acr\/5\/wBTwsmJwk18Bq9oAPjiPyrp5ozLk7QWxxqVxRyQFy8bsj\/1CPlTtAWLxayb\/rqPcUWgstHELQ8p0phZYt1bt8M0Z\/8AkKKCyxZEbk6n2NAWSyDyoGfUAVyQxS\/4kSP\/AJlBpVYFLcPs2+K1gP8A\/GKXFfAFB4Jw4gg2cODzwMUcUBD\/AIBw3IItsY8nb+9L6cfgLIS9nrGT8Mi\/5W\/vRwQFf\/ljhxhaJkdg3MsQT+lVFcVSE0m7ZQeyXDwgRVXA5ZRTQ1aoEkil+yFtlWTuSV5Zi\/1pcWgpA8\/ZDUrd39l1EYBKkYpty9UJQSKF7ISZPeRWzDppcj9qlcvdD4o\/KE08vcd0jsqdFRcfn\/s1EpHRQNGHTxAxq3LVzP1pX8CO6myDOruOQeR9vkOZpN+2Vr0wqOR0XBRQoHQAfOhsSKHuC76UyT1Y9KLsf5OuMIS6ljUsZSoVtznB\/DneopdjRZp6Rpy2B5CkOyx0CY1FM03SGMeC2cPETNCWENxjMTMfAx\/lb+XPQ\/WvO8vy348o\/DNYY+cWyi5s57O4MV1E8Ei81dSK3xZ8eZXBktNdkbe2lvbpLa0jlnnkOESNSzMfb\/eK0e9BdD9OBx8NuRFxWXvWdD3sdo4JiONvGQQWHUDbpk15Xlef9PIox3XZtjxuUbD7DhXZh00snG0mIP3ryxMuT106B+tYS\/VVFdP\/AE\/4BYJL2L7jspdLKzW9xbPbahiV30Hf+nmT6DNa4f1bFki3LTQnjadDSz4NZxRIWCzlidfer4ZB\/lz4eXTf1rg8n9Qy\/VfF18HRjx1GmM5uzHBbmxWCASWcr5YS6jKFOeoO+Pnyrnx\/qzWVZJ9\/6EOH2uPoSR9iDZvJJxORZJF3EcR8LDodXMg+mK6vL\/W5qXDHGvyyIY0+xX2isYY4bG5t8rHJG0br\/K6nfHuCCPSvT\/TPJ+qnGT2ic8eLI8IvHgQKrfAcr7Vz\/q\/iKVZF10\/+Tq8LIpJ45Gu4ZxGO6PPfrk718rnwPGaThRO5vAL5FyNPI1MMT4NgloPW5CR5HP4WHpWDg26CjomWdQ6kMDScXF0waoh37ROFY+xp8FJWgqx5w5jLArAE5NceVcXQyfEQptHi+PXs22xGeXzrs8bHjivqdtdC3YRfcLkFuZ7Tx6sO8RGTkDcr58htSyuKlQ4TvTFttc96JDyAY43ztXNPHxpFSXwTeXIxUqJJRBEXn1dK0lKlQ29UPbfSI8YAI3rmkyaKOJXghtXkJ3Udegp4oOcki4xsQWVtd3KEpBJI7nWwVSzAeZ8q9mWKVUukXKcUqs0NmNEUccisGXKsp2I361z+VLFcHLaXo5op7GlkypcxyEDVoK4BxlTvj25V2Yf1LN4zjkx6a9eq+CZ41KLixlIZCCYHJ\/pbc\/I9a+h8D+1OPNNYs64v59f+jgy+HxVx2Cm7lx+E\/KvqfqM46Pvtj9UQ\/Kn9RhxPvtvnCh9qPqfgXE79siPxQY9jT5r4Cn8nftUH8ko9mo5x+BUz4XUHR51+dPnEKZNbxB8N5MvuKrlH5Fx\/BcnEJQPBxJh\/mzT5L5Dj+C5OK3g+HiCH3NHL8oVFicY4iPhuIX+Yqt\/gC1eN8TXmkTD3FG\/gCwdob9fitVPtRv4GTHaW4Hx2Z+VH9BbLB2oUf4lrIPai0PZIdqrX8UUootBbLF7UWB5mQf8AxotBb+C1O0fDWP8AjEe4o0F\/gvXjnDmH\/qF+YNMLPxDLcuzAyyAbbLz+Vc232zoqilZVDZyrv9cD9qWkFt7OtMrN4HIP82DtU37TAr7ovu7ny55NFP2OwgEJpTSNXm3T6U38AWSSIo1Mwc49aTYJHI5O8OMAA8+mKl7K6LGchcak046bn8qTfyxlYZpMNkIo3Az+dL8sY+7NsO+nwhIKjduvnXg\/ra1B\/wAnV470z0O2EHFOEx2\/EI1lTTpBPxL0yp6GvmVmyYMnLG6aLlFexPZ8Jm4Gt3DYLJcXs4ILxAllh6LtyLcz8hXveR+qOWKMV9rktmcMSbtlFhwa9vNxCwmU63SbwE55YzzORXlZM+OK3I6m6GC8Ne1GJ43RhudakZ9q4nmU\/wBrJ2OuE8KEuJroHuhkKPLNYz8iteh1QHxGyF0RHbqFvIho0rsJgOXs35H359uPOsiimtmsXw\/gptHLQrqyCux89q5cqqTFNU9DiOVbqE2lw2IyuFc792fP29KrDm19PI9evx\/6MWqfKJjr+xPdXfD7rwujZ8wGB2Ptj8jXpYc0vGzRn\/maSiskbRkAHjlKtsynB9K+yXHPD5TR5ycscrXaCbS9a2mLAkZHKvnfL8ThLg\/6HtQnHPBSQdaXhuZQ5O5OK4cmLgqIarRoHuB3Tgnpj\/WuBQ2CXRDglzI4u42A7tRs3Majt+m\/yrTPhVKQZKVM2lrwOz4lw63ngllVowBJCCpG2xAI3Hn1rz83kxw25Lb6+GZRbsNzFbwiJAI1XYKK8+3kdsYpuJWklGDgFhyr0ofbjo24pI1thJ90NTchzrjc+V8jlaM32pjFrfLcRYCXAOrp4xzPzH71phfNOL7RtB2qFyTAgeLntmqcGhsYwtoxjl1rCWyAhrlUUE\/9qz4NlJGev7trq6SAYMZbU3y3H7V6GLH9OLn7NapWPOA31wk6W805a1kkAZZN8D06ijNnlOHCTtHNKKTtGnexhnQlW7t8YBIzj3Arzk1dsOTQkLTW\/EhFOArq3uCMcx5iu2clxtGqpxtD62nDAefWuFO3TMpInNbGeVTCMknxeQ9a+x\/Rv16OLBLD5D3Fa\/K+DhzePb5R9hkXDoIsMxLnzYDH0rk8z+0HkZlxj9kfx2OGCMd9nOIRQtBIBHCpCkhlUBht0x+9c0P13ycNrHO9e9miwRk1aFV1FFE6CGRpEKA5Yb565r7n9P8AKjnxpJ26TOHNDi7qgfFd5kcxTDo5RYiJFAESBQBEigZzJ6E\/WgDneSD8b\/Wi2I++03CjAmk+tPk\/kKR3\/iF0vKd\/nT5y+RcUff8AE7sH\/EB91Bp\/Ul8i4o+\/4xcgeJYW90qvqyDgiJ4wT8dpbt8qPqv4QcDh4tAfi4fH8mIo+ovgXF\/J+Y3jbfrj1zn+9ZOzoOJGBH96oJPqd\/lSdAiYl0gLHG2r12AotdjqiyWZQwAxqB8+VEhLrZZ3i6cySZJ+Zov0xk\/jYKwbGN8tjahgvwXm0YwCZIWa3BwZFGpFPkccj71l9THz43s04yrlWiQzowqKiHqeZrTfbJOxjA2yxY8z0qdjHvZe3aW9ljMiJqQEk8lAzk14n60vtg3rZvg9m14TLZRYtnvJ+8UkArbeE7+r5\/KvnJ4sLuUm\/wDJUdEoyY5tFaJS8cyTAsXYpnO\/mDvXD5OP6knNO\/8Af\/Ipa0XWv3127A7lAyk8snmP0NU8Kfj1LTXv8fkeyy5u1hj0zRtIrfgGN\/mdvnvXHi8ZKaeS0vwN36IrfwTAa45rfCMqqrhuoPIjBxj0r144\/EyYvpxTW+\/f\/v8AgzqSdme4lK1vxANqDg4ZXXkynkRXO\/H4Lgzrx\/dEJu3SRTdxgh2wJR0Pk3z5H196z\/ct9mdV9rKo5sb8qzlEllXaBRPbRXy7vEBFL6r+E\/t9K7sM3khxfaCOvtMLxSMG71jYMN6+p\/SM7lj+m\/8At\/2ObyYbU0KruTTJkDNdnm4lOHL2h+Hk4z4vpk+EXOm4ZCf6hXieRjuNnoT07NPcT4gWQsMkda8uELlQoP0M+EwmLhok06e8bXjrnp+VZ+Q5P3pGc3cqNX2SvY7Nro3EmmNkXA5kkHoPma8fzscsiSiJIIv7pbiRyhMYY7DTk\/lUYcXGky13ZOz4fazESPcTEg7hVC4Pkc1cssovg4hKb9Glt4bNYgI5pw4\/+ooYZ+WK3xLwM6qUnB\/naOd\/UXoScZjbinASxAjlUiQajsjKdx58s1zY6xeQt\/a9GsXxZnZAlpEpE0Nw5YfAxyM8+YHrXdLCm9S1+L\/4Hbk+ghpGibQ6lTjbI\/3kVzzxSi\/uGqYJc3MrlljilfSFJKqWGCT5b9K2w+O5K0XGl2wHhWr7ewkDKwQnDAgjl51r5EXHH\/U0yNOOjQ8PgywbGMb15uWdHOx8vENO2reuPhJdBRTdrLxGWA20byzxnkgySp\/sd67PD8fNnbxwV2HOME+Qfb2V9AodrWRs8iuGA9dia6sn6R5mJXw\/2ZksuOT7G\/C7lJJDbO8a3PMRM4D\/ACB3rHxf0\/yJtqt\/l0\/8icsorYVcy6CV5Hr6Vl5kcnj\/AG5I0KCUtoS31ySWx\/Kf7fvXnwuTtm6VAQk+9jUHmv586+3\/ALN+Q+cYP4aOLy4\/a2XV9secfEUwIkUCOYoAiVoGRK+lOxECKBkGG9AECKBFbCgZWwoEVsKBoqbnQBUwxQFHgbTBvgbG\/Inl9KLZp+Cl5D3g+Ejq3ICk2CRIBVOrckjIHSgfZ2SMggkqMefKpGVOcshCswJ5kDB9hTtCosSZdWA5IHPG5zRf5CjWdhbt1u5yuloSFLagGDKTggg7Ee9fPfrn28ckXvZ1+O\/tcWb7jfZPhPGYHayiisLzYiSJdKMfJlH6j868Pw\/1jPglTfKP5KnjTPMuIWVzwviEtndIEmibB2JXHQjzHrX2fjeVDyYLLD2c0ouOjUfw\/iDG\/ncBiuiMbb4OSdvkK+f\/ALR5WlCC\/LOjx12abh9gvfSyEZJY18vlzOlE62FaJbWdJUYhgQQF29hRhyfcpfGyWr0QurkxgTSnMgYk42yc1fKWVtvtnTDGqL+C8RuZI7xu4mktTmTwpty6HlTcZwcYwdfJGWERjeWavKvhQOcFGGyt5ZA2+Yrb6ksGfhkSv8dP4OftaMfcv9ot7mADEts7OgPMDPiX9\/lW3LpPpnTH7Wn8kuF3QMIV91IIOOorDJHjOwyLZQZe6ldGJOk7etU48laJYdaMk6SQS\/BMpQnyzyPyOD8qWN8JpmbMXxIEMUIxJGSh9DX0H6ZJ486T9izLljYTwXs4vEIkur2RorQ50hCNcu\/TyHqflXo\/qH6jj8a4ds4sUG3aHFx2b4PcXdqtlw25tZcgNJFdHQFweasCST715Ef1GGSDUo7O1PJ7djePsj3FxE0sgubKM6yCMNkdCBzH\/avIzeQ1FuHb0VHJsmLeW5UFRhCS7MeQyf1rmnmUUo2D7sPhtUjQYHzPOuSWRtjsm8egEqC2RyPWkpW9is5cSzuEAmkVPCxXUd8YIz866l5E+PFhGKHvDOLcPnCx3MU1u527xH1DPngit8eH9Pyrjki4v5TIn9SO1sZK4jSW1n7ssuJInH4kOzAeYz9M1vl8SvFlhlTlDcX+CFK5Jr2eUcSSReKy2aNkxzGNfIYPP6VOJJwUvlHcq42MEvJbW1S3iijkjDaiZSZA3sD8PsK0WeNKLirXyZceTuwiG4eOU3NrqtLgrgiPZR5EDp+m1XOaglkSqS\/2Eo39r2h7I03ErW3ecaZ1XBOcq56nHMfnXneR5UctKqomK4MpiR45ND5DDoDXBMvsu+zyGVmAJjzkDz86jmqr2VeiT2kjD\/FfT0ANaQ8qUVSdEUBrYujgoxVs8wcH1raPmTXUmDoKt7MbmbLEtqJbc8v+1ZZM8pPk3sPwhss0qwpiQsAMb8wKqfmTyY1Ce0QopO0UTXBZgSD4h+eeX6Vxxgl0X2UrJniqhTsG0\/LGP2r6H+z0mvJxpfk5\/JX2MbGv0Q8o+NAjlHYHKYEaBETQBEjNAECKYyBFAiDCgCpqQytqBMqamMpb2pUDPz8Ci+JVJX+r+1F10albSAnwnLdADsPy3pX8AfB3VxqBJA\/3mi9hXwTM\/hLEgtnG4zii72C+EWR6GXJYnHM5zn50Ug36OKwOQgULjckUfgLNB2QbF3Op27yMEfI14X65D+6jJen\/ALnRgf3NM9RtJm7qKQbK4B9q+Ny4XjqXpnV3oB7T8HXjturwzCG9hQhG05Ei9FJ6eh9a9D9L\/UpeHJp7izKcOQo7BwvZSXcN6jRuJFVlfYg46iuv+0WRZvpzxu1T\/wBx4ItWay2DJNMSyKkSnWXYAbcvU5GOXka8XF4r8mPJaS7b\/wDuzpnJJfyGxR27cPifiIc3AGW7l9K6\/QEE1MJ4U3DHBtv8\/wDgj7k9Caa1jvLgzRR3MsMT\/eIwGk\/06tt\/St8WHLwcoxr8myzUuLNBPxJ5eFzxCMf4LKirggbYxgcq44wywkk9mNK+xfwe7D8ORSoxEdJ9RXZ5cPq+OpJbiOuM\/wCSri1ks8iTrgTqCFkPNh\/K3n6HpXJh8qTXCXRfRmLyFLOVBBrMQRTIzrj7w8wPQHb1xmvU1OFezSMnPsE4jNmWGbVv8J9fKlijpxFXaL7SfDc6yyQ0Q0CXtmL3jZB\/wn+9kx5DYj5n9a7MefhDm+0LpUaWKNSiqiqqAYVVGwHQCvKy5ZTm5S7ZKXwXrMsKyMcYzzx05V0JJLRtw0au1JeNTkDbIFef9XtNnM0L+KQi30PEMRscEDoaz\/c7NIsHiyUXPIis32UfS+FN+nKnHsQulnBYE9FA\/M\/2rpjDVFpUUB8YOc8hVNWA9seKf8n3c7EhCCp8gdiPp+ldmPybxSxT+Nf8GTx\/dcQLinD45eJSTKVDyABiBjI8xXJjztwUb6LukfMkFlAzxRKGAzqPxNj1rb67l9qRK2I7R5HE07NqGsfVt\/kNj9a2zzckotnQkujVcMkDW8RB2xXjzuMzGSD7iMMobG4H0pN3tkp0cs2kAxKBnpj9KxlV3E0CzGvMbA1g5bADmYJIuefi\/StYW1YHZf8AEcry1aQB6U+6B6Og460kxFJIDjyzn51SAo4dluIRhujE\/lX0n9n9+ZFfCZz+X+xj\/TjnX6C2krZ5QVNDFZxq1wS0x3EYHw+9fI\/qX6823iwa\/J2YvH9yM3x7tC8YK2sMfeHZXlGTnoMD1rg8D9Rz4pcMcnK37Ol4IT3IaR6zChl0iTSNQHLON6+9XWzyn26PiKYjhoAiRQDIEUICBoAgaAK2oAqagClxQgKm50BR+eFl1bn70nfGCBT7NNo+MuTsGDf0jYVNj6IEuN8EjmWPKkHZW8iYO7L64\/KgEiUeyfGWJGwz0pdjOQse8w2MDkB0p+gY94NcLbX8UzklFyrNuTvt864fO8eWfBKC7\/4LxzUZI9P4Ddh4RAxG3w+tfIxa\/wAOS7O2S9oLdzGxxtXnTxuDaY1tESUlkaQAB9IyfPHL8qhylSi+i4Iq+0y3GuP+VVGcdc7nz5bV0t8cUYLrtjSSfJhF+txeWiqNCR4xpUbn1Y+ftiso54RlUY1\/5FHTsqs+8aGHv5ZZVjH3aO+QmDjYdNsVpnzzmqb0huKT0MUKqNQJz0xXntuwoqtYnilaZE1JKDlEGT74r0\/HTUPuVpibXV9DC4Ro4YtZUxTKHQhgdQrkl4U8M05e+g5piLivdJPH9o3t2YJL5hTsT8tiPavX8KF3Fjhb0uzJ8XSS07+CUfewPpb5HmPcHPzqo4+M6ZqpJ00V2NzllGrNTlxksb8PId55epYRj5bn8zXLm+1KJDVjiOYIoGehya4nC2XFWDvOMHHMkA\/XO9dEVqjpa0aWz4jHFCihS8hGTkdK89xq9HE1bCHd7u3lDgDI8PoRuKmK+6xLTFqXIVdLHG2abhe0a0RmulKsCfce1OON2FCK4uPupHBySzFfYDA\/Wu6ENpGijskshSNNZyQo2pNW9EtFtvI8xMUe7Hb29alwS2xultmhU6kAdtWBjV61ycePRg3bE3aS8ENiwLYY+EGunxIOc1ouCtiixctwcTNnxzk7dQFAFdWX\/F4r0jpS2aDs9diW1CZ8SMR+ded5ePjKzDIqZp4iDDj61yRe9mTI28u5B3I8+tZTVO0XF2SM2keYqONlCu9uVPEIlBzkfqyiuvFjf02UlaL45sxKT8Rz+tZSjsT7JGXypcSSp5MHNUogX8OUG+Qj1b6ivoP7ON\/9Yl+Gc\/lf4bNPbBLeI3EuNR2jU+fnXsfr36pxX\/T4nv3\/AMHJ4+L\/ALmIuMX+BIJDl85z518fbb\/k7UjN8FgPE+NGV97e18Z8i5+Efv8ASvrv0Dwd\/XkuujHycnGPFezYV9aeaRNMCJ2oBESKAIGgCDCkBWaYFbc6QFbUwKmoApagZ+e0tlQagxx5Yzn3oRpRwlQAGkIPTwjP+lGkHZYUDrk6tONtqG7F0wbuQzAAA71NN6K\/JZL93HgLgZ+tFfIHIhkkMoUjc+lOvkB5wLgV5xYqLSS0JLY0vcBCPcGuLP52LxnWXT\/g1jilKPJG24dwfivDeHK96sOIzjMUwcgdCcV8j52fBmzOWH2dWO0qkMhc\/abXUf8AETY1hNfUjvtFVTKoJvBIRzArllDaNYh3B7cPCJCN2Oo1j5GRp0JjOdESMkHTjp51zRbboa7M\/HdKIWy2NDcj5Zx\/avQeNtmnFl8l4sbAupKY5cqjHj3siiP\/AB+G31Jah8F8jvDkry5Yr04y+nGscf8AMlY3J7D4+JNfKJGxjOwHIef51y5sk8k1zfRMoqOkAdoWD27K2AxXGfOu7xp\/3yT7KxKmIe1Rabhlrf8AWW2Ebn+tBzPqR+ldeWP99TKqm4md4dOQgJPLpUZoboqWjQcFuB\/wpZGIBLu3\/wB1ef5MP72l+BVYcLwPACdxWP06kawjsBvrrTGSNtwMkc66MeO2bS0h9wybvCJJW2boPKvPzxrUThfY++1jusR+EVxKLTIEN9daLhh0O9duPHcbN4bQruuJlE3PiJ5iumHj2zWMdi+5vTpKjdlVE38zua6IYvf8lKIZ9qLxopO561j9OnZFbNBwhO6iMh3dvyFcOaVukYTlboNmuEVCc4zWKTbJSMV2lvWup4YEOWY7gfQV7Ph4ljTmzoxxD71lteGxWyMAIgN\/Xqa58ac8jm\/Zquyjs7xEx3zozeF8HGetX5eDlBNEZFas3treAoN8npXhyx0+jmaJxzBbjOcahiolG4jiRuJiFkBOM8iPOnCF0aCWK4MnE8k\/Dgbn3J\/Su1wSxmi6DrK4D24AbGNs+1YZIVIiSLFnJzk+1Q4EnGlpqIDTs8UfiAaQ+BYmYjzx0\/Ourw\/Kl4k3kit01\/mZ5oqUaGPFL5mYvIBjGMDoPKuablJ23tkJejI8Vmlvrxba1GuWU6VHQep8hXo\/pvhS8rIor+oTkoK2anhXD04dZJBGdR+J3x8bHma\/RcOKOGChH0eXkm5ythJrYgic0gOGmBE0CIGkMgaAK2oArNAFTCmBWevWkB552r\/iNNwPjEtlacPtrhI8Bnm1Z1deVdUKSpJMwlt7Z54koiIGFCjqdya5ujqq+gnvo3+HxN7AVTYL8nzxK6Z71ifLPKih2UhSrLswA577mp\/gCm6d2PhXSR1I\/Slv0CKYz3anfGfPmaLHQ+7K3n2PiK9+AYZPCSd9J6V5H6v4jz4eUe4m\/j5KdemeuWF33mEBwAMf32r4KScDraF3EbAWeu7t89z\/ANSPGwHUj28q68Gfk0mHapiWSUIJwp54INdDinJGkB\/w24KRRnppHLoa87NC2xstvbpAhAxnp61OPG2wRjXuitxKjYAc6cjlv+2QK9mOO4po3Ox3\/ewgE+MDGP8AfzqZYeLIkt6B2ddXPbNaJMEPuGTqtlCcgcz+dcmSP95sxntsjxqcOmpWBGMEV3+HC86bHiKoCbzs\/eWYAkmVC8SsMgkZOn0yMjbfevWzR4ZFKtB5MG48o9mGiaKSNjaMwbGe5Y5YDrg\/iH51pn8fdo4sXmc9ZOx5wif\/APoyKCCNR\/WvEzw\/vmz0YLQQLjShGeu\/So+ns3iqF3Ern7sAbAHOK6MMNhNjDg3EcFVBzjl6Vz+Rg9nJI0y3o0bnJxzNeY8TsgT8Wut1bVjGx9vWuzBj9GuLToz0l4WcoDnLDl1FehHF7OitFUl1qKb51uz4z8h+Qq1jr+hX4HnCiJCGJOlOfqa4c+tGE5V0aGO+076tv0rz3iswoX8V4uscMgzggH1roweK5NGkY2ZvgzmfiqzSEEqc\/OvR8lKGJxidSVIYcYuCQcHz9cVz+PBAKLS5KXKMraT711zxpxoUujb8I4gGjUg14vkYaZzSQ3lu9Kh+eN65I4r0SuyN7efd7ZIxkH08qePFs1WxXYzZmuGIOoEkZ9F\/1rqyx+1L\/wC7L9BNncaY0G2joBtvWWSFsJUw2NzuWO3QVhJeiNHzy55UKIDqwj+ywM0hHesP\/wDEeVZzoxlK3oE4hfE6Uj1MzkKqKMkknGAOua28TxMnkZFjhtktqKtmw7Mdh72ztjc3fdC+mHiTVnul6Lnz86\/SPA\/TF4mPiu\/Z5ebyPqPXQ3fs7fDkEPs1d\/0pGPJA78C4gv8A0c+xpfTkHJA78Iv1520nyFLhL4DkgeSxuk+K3kH\/AMaXF\/A7RQ8Eo5xuPlRTC0VMrDmpHyoApkOlSzHCjqaai30DaRS8iadWtNOM51DFX9GZP1IkEcSIHQ60P4huKhwkhqSItSpjtFRxmkM\/PH8Q5B\/5p4gDviU11xqjE40awjDMJMdGb88CuU6tk4ZEZiExv0UYpp3oQfG8dzbRFQiPEhDrnd8E7genL5etZYsnJuD7RnGW9n0cuoELjT6AnFbp+jR7KZIsZdhqJ236UnsAaePB1adI54qWqGWWoRkReYHMAGkqfQ6Nx2Z4wTiCU4dcbk7kV8b+s\/pv0pfUgvtf+h3Ycn1I77Ru4ZVkiwdJBGN6+XaaZoZzjfBjEhlsw3dgeKMblRnmPT0r0\/H8jlqfZUZK9g9pdaFxnpRkx2zWvYJxG+whUnY7g+XnW2HDbsF2Za5udVydyQQV9vKvUhComl2ij7UUkGDs2\/tV\/TtB2Ei5yc5ycjFZ\/TEjQ20oWzhAIOEFefONzbOeW3Z9dzGS2cEb4yDXo+AqyjjpkOD3Zt7pXVsbg\/nmvX8nHzi\/wdD+6NGY7SG0t+0F7bXIa2dJdUc8I2KnxDI89+YxyrowyjlxpS7Pns2PhNovtrkfZAFlWQYLF1XTq38vOvI8zElmPX8Jt4lZY8x04BOMc81zKJ3qgDiE2oO2rGMY8\/et8UaIk\/R9wy80jAO4x1oz4jml2aKK8LjY15ssVEoheMDbyHrpNVj\/AHJFQ7M1bTMzNJv4VJx616U4pJI6m6LGYtcRxjAKqq1NVFsOVbNBBKIECqeXP1NcEoubs5m77I3F+QpwelEMNsEZ6fiJnlZWYnfOK9OGDgrNsaGfBZQjg9a5PJjaNbLuIyh4iV51GKNPYCbVqI2rrolmo4LceBMHwjYYrzPIhtmMh5Jcnu8DnXDHHshIqmmPcI+rbTjHqKuMdtG0SixlxHM5IyQ528thWmWO0v4GW2NyupUzkKBvUZIOrBjOO45jYe3WuVwIoMsnBl1tg6TsD51nNUqIm\/SGNxeYTcisIw5MzSol2K4ta2XGZuIXNo113P3cGGA0OfibfrjYe5r7z9CwLxcbnKP3P\/Q4vLuVJHoifxEsv+pY3K+xU\/vX0H\/UL4OH6bCU\/iDwdvjS7j94gf0NV9eIuEi9O3XAm53Mi+8Lf2p\/Wh8hxl8Fq9teAN\/+oKv+aNh+1P6sPkXGXwXxdq+BSkhOKWuRzDPj9aayRfTCmELxrg83w8QsW\/8A5Vp8l8kgnGls7\/hF5BYXdnHdSxFYpVdTpbGxp2vQM8ik7G\/xBdSkfE7G5j6g6CD+VNTyroiosBbsn\/EG2heEWHD54mbUy92uCaf1ci9f7C4R+TgT+IVpGI27OQtGvIIpA+WDR9af\/wDEfCPpg5452st2\/wCZ7JzEf06v7UfW+Yhw+GUy9s+IRZ+09mLyP1G\/7Uvr4\/cR8JfJ5t2it7LinE5r2ew4hC8zFiCvWplkxN2nRUVJCq3lyNJCKD6DH0rnOkIgjiGdTscfy7CivTGwGVEh4uunUsdxGQu+4YHP7fnWGXHyTcdMwyL2M7HiHfSJa3LiOY7JJyWT36BvyPpRgz\/UVPsUJ130HyQMjac6Mc9Q3rq\/Bun7RQ9oCzENkjrikAGkTRTKrZO+Sc1FUx9h9omljIhCkbhj51GTDHNBwn0yoTeOVo2PBuN95GoZgHzjGetfBeb4EsM3Fo9JNSXJdGqjuFaAHPTevKScXRJmONQiKVpIsKGOSOWDXo4ZXpmsJ6pmU4hcaiQSc9Qa9PFCjQQyzHvPnmu+MLRROWTvELDkDq+tTGNOgTJW7l9K4wW8jSmq2EtGi+1aRjlgY3rz\/p3swKHuyU052J89q7PDx1lQeidlcBcOCdhn1r2pK9G8XaFX8QZlbitjMQo7+1B5bEqxH6YrPFipNL0eP50PvFdtcBbNQNhqI\/euTJjfPZ2\/p7vF\/UL7\/Ma7n51jw2d7dIEvJw0bHqQNq3xY9kORTw+UhsA+tXngc8nZo7Sc4G9eXkgSFtLqXntWSjQ0Z+2PhbJPiYLjy3zXoT7OlsL4f47mWYjIUnB9ayy6iokZHqg15STXOomVi3idxpiOK6\/Hx3IpCm0b\/md9\/Su\/NGo7N4bHfDHIklB5BcbeZrzcy0htn0lzrhGcZ5ULHTHYAZPFgttit+ImzQcEl0qp5VweTExl2ORNqOOlcXGhEZpPumB+H9KcY7LT9FdvOEsWzuTGd\/c1U4XP+pZG2uNTbN+dOcNBY0tZGZiWJxXLOKS0RKXEYwXIHKueUDEp4jflIiEJLnZR5npXb+neL9XKrWkDHfD7cWllFDnJUeI+bHc\/nX2cEkqPOyS5SbCDVkEDRYis7UwogSR1oERY\/OiwK2x5D6UrHRWyr\/KKBURDMhyjuh\/pYihOgqyxb+9iOYry6Q+azMP3p8n8icY\/AQnaHjMQCpxa+X074n9ar6k17Yvpx+AiPtb2ijQsvFbrSoyWfBAHqSMVSy5PTJeOC7LF7bdoNBb7dFMgOkkxxuM88bVS8jKumJYoMqftjxVjmRbFz5m2Wn\/1WT8f5A8MTwRo5FcAvsP5cYpGhdCTz3bfbIwKa7CwTjrlUtpgTqSQ74wBTu9EZAgwpeQ6ycatx6Hr+deTmbw5Licy+Aqx4oyFbTiLHI2jl\/v5ivRxZ1kjbKjNw2uh2fiwrkqBn0P+lbo6FJPYK4JkGcA8gBSeyui0oiNpZ6NBfwfOxi+8ibxDcgbZri83xo5oP5R0+PlcHT6Zq+B8XE8CMzfhz9K+J8nxuEtHZJbPuMXQaNhmlgx0xGVukMqNhsMN816sHxZcZV2Z65Y75NehBGpO2k1xgZwTlTUzjTFZbw5gZvF+Hf51OVUtBJ6GLz5HPeuZQoyX5KFmzsSd2HWuvx4f3iAtt7jEYGdwSK9KSdm0HQF21xccL4VN+NHkjzn2NaY7jJ\/wed+oLpiTh85Nuysd1b9qy8jH91o0\/T5fY0wrvSI9hneudY7kd7kCTSlhzrohjoyvRbYtvnkOVY+REzbNBay4AGc15k4iQRNcJDCXkOw5DzrOGNydIpbFkLYiTc5wWOfWuqS2bWF279ymnOfM+dYzXJ2ZSley3vRjNTxEhPxKUv4emfpXf40F2XEHsjhy2NhyrfOm0oo2g9WNeHzBGlc88iuDNjekgbBJ5cPMgO2okDNaxhpNgmUl8sD0OKtRE2PeHyBUT\/eK4MsbbM2N0m361xuIHLu6KwMFyKcMdy2NfJCWbRasNzgKo8\/9704xuRVldq+oFSQMeXWqmq2OxrFNoGOWwrllGyJliXWkHJFS8dkhPCNN1xNJX3jhGvHTPSvov07CseO\/bOfPKo6NR9pTyr0rOE++0J5GgKPjcJ50WBAzx\/zCmBBpo\/5hQIr71TkaqOwog0qgfEPnQB1Elk\/w4pG8iENFE8ortgvEbu14aueI31nanoks6629kXJ\/KrWOTVkPNBdGb4h20sI0YcPhuL1xsHZe5jHrk5Y+2BSqK7ZLyt9IVC97VcZ2tybO3brCoiUf\/M+I\/WhTS6QcZS2zQWnBi0CDjF3PxOQb6Z3JiU+icifU0SyN6ZrHGojGGCK3BEEUcY\/oUCoqiiR38xTA8eW+lAAZMDPPlXTyJomLqQ4PhB+pNFiLLtftlkyElnG4x0IpSuvyElqgXhNwU0xMSNey\/wCYbEfMYrDyMf1Y\/wCxytBt3ClzHvjPnXm45OD6JsqsOKyWLC3uwXiztk7j2r18WVTRadO0PbWdJcSRNrUjAZf97VqdClaLwy5xpDHrttS09DRMEd5qA3Hn50vyNC7h183D+IyQMfu85UHqprw\/P8NSto9HFPnFMbXt+JM5PyryseGiroFWQEe9a8aGZ6ZiTht9yPWvRgjayu0c4cDGQQd6rLHaJbLtfdXBKk88gVCjyjsOVoKeRXXOdqxUaIKFmCONbbZHWuvBH7kx1ZbFJoklTqDmuuSfZcZFPHJRJwqBSclZyR7Ff9KqHZy+fXFMT25wWI57Z6UZFf8AQx8CdScS15MgjrUJUz0JyBw2cZ9610ujPsLtHwBnnXNminsnsdW7\/lXnTVACcRnMkoUE6F2G\/WtsEOKs1WkS1gZIJOMKKniOy8Sb4zWfEyJSyaY8g70QhbGmK7ttXQc8Zr0sUGik6IxHShA3J9KWVcpGqdItE2ghV6bbVm8d22K7Iztk6s4zRBUTZBXIOR0puOmPkMbe5KKmDvneuOeK2yX8jmCfUoNcUoUI+vbgEKoOOS08cPZd62VT3Qkhk0nbX+lVHG01ZKkmW2DFckkHyqMqspMMM+XbeseGhSeyp7hmYIvNvLfaujBg5yRN+z0PgfDxZcPRZB98\/jfP5D5CvoYRUVSPOyz5SDTCp\/DVmZW8CjkMUqGVmFc86ehWyPcr1GaWg2fC2VwdK7DcnkBQl6REsih2KLzi3CbXI75rqUf9O28X1bZR9T7VnPLix\/vdf7mDzyf7ULJe03Ev\/wBOs7WyT+Z171z8zgD6Vzy\/UYRX2R\/zIfKT+5ia4ueNcSkaOa+urgvzjgOgfPTjFEPJz5f2qgjD4RZZdkWPinMVsp5qg1ufc8v1rZY5Pc3ZusfyOrXglrZlTAilx+OQam\/Pl8q0UVHo2SS6QYRKdy2cdaYaInvBjDc6BkNU3PNAETLJQB5jcFWXwgbjnyrp2Qgdi652LDkCedK17HRbEWOxYIPIClYMDu0WC4IkJEMuMtjdG6N8qmOnRz5I0w2CcyBllAE8ezgcj\/UPQ1yeTh39Rf1MWvRG4ijuI8NnUORrmxylB6EmL7e4uOGzkqcodip5NXp48qmtGsZezTcOvI7xAYCQ34kY7rW\/ZrGSfYfspCsPcc80mi0xP2kDr9muhgMh0HT9R+9ZTipdnRgnVxAoL4sAM8sbV52bx0to6k7GsU2VG9efKA7FPEPDK\/LHPNduDpWaJgttJic7DB6VvlinHRLkXzOMIwPocVjBXaBSLI5fu9\/1qXC3oGwa5kI+EjHWurBHexWXiTWVbmGXJromtFJ0fcQGqyBPRwPqDURe9GHlO8exQrYkB89jWzjyVHn4p8JKRZI2FIzUKO6PVnL2Vht96pk2FwNtvisckRpjZJdERbrjavOlD7qGLQ33wDHA3NdTiuFjci1ZdSJ1y+fzqXCmwUrCg5zt0rncBWVzy5A3yK6MOJFJg0rYVABuBn2zXUlXQXsir4XOfQVPCxuVaIptg561VIXKw6CLvfAOZ5e9c03wVsmUgOTUrsu\/hwd63rVkxybout3B2PtvWGXG7s0chtaTDAVcVwZICsG4pfEA9MAnatvH8e9iyZKF9leOY2TI3I\/SurPgSaZjjm\/ZobObEWpjvivKyQt0dMWfGfrzwM0RgF2aLsJw03\/EjcyLmC2wTn8TdB+9ej42KtmGadKj0giu2zjIsD50WwpEGFKwKmXl50wdIT8S41DaM0duBcXI5qPhQ\/1H9h+Vc2byoYf3d\/BzSzOWo9Gcvrm4vSTf3BdeYhXaMf8Ax6\/PNeXl83Nl1HSMaRG1tpbs6LGDUo2aQ7Ivz\/YVeLw55NyNIwchxbcAiUZvJGmb+VfCn9zXoY\/Gxw3RtHEl2MliSJBHEion8qjFdBr10RYYpgcIoAgwosCBAJzTsCOnAxSsRBlx0ppgeThTgEMB5sa6GSWxyhSTzOPp86PYFqxxN45HAPvRS7Ffopu7T7RCyoUyNx50pJ9oUlaE0MrtH4WIuLfl\/UnkfPH6e1Wvu2jmYdDcRzx602PVfI\/2rgzYFH7o9CaJSgTJpdaxi3F2hIAaOS1dZIWKsu4IPKuzHl5Fp6H\/AA3in2tdDHTc9V6N7f2roUuRrGXyF36farWaBtmYeEnffoaT2bRuLsyEblHKsMEHkehqJxtHZGSTG1rc+EDrXm5cJpZ9dnWuedTjVMdi4sEcY6b867Y7iZtnDdgh1O4ByKaw9MiOXbRfHMDHkH3FQ8dPZqpWU3DkHbPKtMcRNhduyhU1Hl\/atHVUDZfeRvLwdrkEhY5VUDPTcE\/pUxic3kZLqPwJZNmPLzzW35OMrlYlAwPPY+hoSR0wyNqjqHVy5\/pUtUzpTtBcTYIHI1lJFph7SgIFbmRXK4btD5exVdXOg4yd9jXbjxJpM58mX0i6xmZzGD0GdumaxzwSVmmKeqDdZ1ZHTqeWaxhBdGiZB2LEAk71skkXaSInxOcVW+kS5UVyRvqBGoLyG1XGlo45ZW3ZdFE7fhJqddlxy0HMzWcWI0LXUmyKBkjPU1xuMckqk9A8jfQ\/7P8AYLivF7F2wsM+ksv2htOs9EH9zgV2Ysc5yfqJlLJxX5M7xjhF\/wAGvWteJWstrdLgmOVcEjzHQj1G1XPC0awzqS7IWsh1A7jHTFcWbFV6NuRC8jWWcqZcK45AZIqsNxjtdGOXIk6BLRH5AZBOSa0zTT2ggN0kIUgbkfKuD6dnQpDfgnCLrjF0Le1XYf4kjDwoPU1pjwvthKairPXeF8Pg4ZYx2tqPAnMnmx6k12JUcjbk7YQ3ypiZAnbfnQIizAAkkBQMkk4AHmTRdCb4q2ZbjPGmucwWDskHJ5uTP6L5D15n0ry\/J85L7Mf+ZyTk5vfQieRLdAkS5YnAUDJJrgx4Z5nYlb6HXCuAlsT8TGpuYg6D\/N\/avZweLHGt9nRDFW2PgFVQqhVUbAAYA9hXTZqQagKINzoDogaAKzQBw0AQNFgRNMVHCKQddniyTFt3Z8nodhiu1kBMbF056UB5Dz96jfY2XJA2kMyqpPItk0UKyaQoG3lB686VWF\/Aq4kht7pZ4cAZzsNs9RTjpmU1QFM\/cXCywZWKQalHl5iqoha0MLe4WRdQyPMeVcWTFxdk1Ra51DBxnl71klxeg6ApI9DakJDDeujHN+x3So0PBeJi7ZYLtgJh8LHbX7+tdMXyNIutMSdowkfGplRQA2lvfbnT40jpx5L0waGXC7VjPGvZ1KQX32oEZx1rCOOmU2L7ssH3yBW+ONaOfI\/bF7ticE8s1ulqjnfdjC3k1LjrnOaxlE6MbJyOGbbc5pxj7NbCrSGS5lWGLmeZ8h506t0Y5cvBWaq4s1\/4JPaxDYRHTk7kjf8AankVJHJik5uVmHYgqp64+dC7Ymct2UMVO6tsacl8AtESphlIxyO+1P8AcqNceWtMtgcE7HaolE6oyXaDu7muVH2ddb4+Edaw40+gySSQmukc3RR1Ksp06T0NdUahHZyN8mM4VEUYC7E4ya5JPmzqi0lSLl1Ead+f0qkqZqnQXa20k7hIlZ5G6D\/e1FLsmWT4NJYcFtraH\/mB3tw25IOAvoKZjJ8tME41CtqYNKZWTOQd8HaspwraMMmqob8HtoPs7s8MZfSrAsOWSf7U8cE+xQk26HViILfLxRRI3PKqBgVvGKj0jVmp4JdHvFJY7jnW8JWYzR6Xw+z4V2ksPsXG7K1vY0GUE6BtJ64PMZ9CK6lUkYNtbPMP4z9iOw3ZLhz3Nle3lrxaZSbbhySiUP6sGBZUHnn0FTPB9SLb1+f+PyV\/1LjUVs8e7K8Jk4vxWO21KJJs+JxkAYySRXl5YfbUdG+NtytmrH8OeJK5Ec9lp6HUf0xXN9NtnTY64X\/DqKFg\/EblpvNIVKj6nerWKu9j+obG0tILG3WC0hSGIclQY+fqfU1p0Q3ZaaAIMaBMouJY4ImlmcJGvxMf09SfKpnNQXKWkROSirZjuL8Ue+YocpaqciMc29W8z6chXieR5cs2o9HLKTltima4J0xxAtIxAAUZ38vU08HivIxJWafgXBlslFxcgPeEe4j9B6+texjxxxqoo6oQ4jjO9aFlTHANAyBNIRWx8qBkSaYED6UgImgCJ9KYESKAIk0hHi6zLjwgZJzk12v8EBUMg\/Dgt5Cl\/AggmV8qXAPUKNzSpj0VTRGM5UEHoOppK2JFMwEsDI5QMdx\/Nml3oTVigIZYnh\/EPvE\/cf78q0UrRh7B4JWhkyPmKcoqS2OhvE4dVYE4xtXDkjwdENEW55A28hSSsPyVuu2U2YdfKri32O6AeJSvPdySyMWYHGTz2ruj0VZG3mGcPzpONnTjzemFE45NlfPyrHi0dKkiLgyKRk56UftZE1yVC94W1gHmds8615ROZxadB\/diFAg543J5k1km5OzeNR0QaQIck48tsmtFGxSypaNL2QTvYpnA27zHnyAqorZx5ZcmamNMHSw22FLKvtF47++jzadDDJLE3OOQr9DUL5LfwDnZ+mPOqsQRJ441k6jCt7dDUftJl8nwjVyCPCfOlyaGpuLLViLhndiY4VDac41HNVFqq9lyk8lNjNLKXipkvI1hRy+67jJx51x58qxS4v2OORRVBlp2bubmC8lkubWBLWBpiGYkuBjwrgc9+tXhyRndFfXS0a\/+D\/ZbhHaHjVzFxeOWW3htXmVVlKZYFQMkb43NbYKySaYnmk+jWrZ8PtO9tbWyjhgDYxGuCfnzNcn11FtPo61jbVi7iXCl095Zg+o8q2U1Lohxa7MV2ogeJbbvAQ2s8x6VOToxyrSD+HnCyKNj9mib\/wC4\/wB6qH\/gzg\/vDoZcgA9K1OgaWFwV3yAc8\/KqTJkgfjX8UZ+Eo1r2dZGuyMG6Yalj\/wAo6n1O1bwy1s5ZJPSMPHw3ivGbLifaC\/kknit9LXFxO5Jd2YAKCebb8ugHtROU8itkqKj0em\/+GngUPGO03FLq9jMkNtaaQOgd2wPyVvrUYIRkm2jS2uj3r\/y\/w+3uGEdqTj+Y7VssUF0g5NoIbhPD5RpeCMD+k1XCL9E8mugC57H8NkU6JJIyeuQRWb8eDKWWSMl2j7N3HCUEwJltidnA5Vy5cDgrW0bQy8tMzM80cETyzMEjQZZj0\/ufSuac1CPKXRc5qCtmK4vxWS+k1HwQoToTnj1Pmxrw\/IzS8iVejjk3J2xHdXPPBIxzzW3jeJyapC7NR2Y4SbWIXl0n\/MuPAp\/6an\/8j+m1evSiuKOvHDirHxOBQaEC2DQBFiDuKAK2NAEKAIE0ARJoERJoGRLfSgXRwmgCJPzoA8N69Plyrv1RmGWvMaQwz0FZ99AHhygzpA9aLF6OZ1eJt88jikUj7ZCCABncDrQlT0FiriC91c94owM6v71UTGapgd7Dg60G1OOtE36I2c+hwpPhNKcOQmMAcjauTr0TVENWG3pV7DYvutpnJ867cbuNssHOxyfOtALYyehPy6UilJrosErIc86nipPZayyLmuV0RiMAl1yxxjSc4x6\/61H0ldj+q2fXBZ7MOCQVbB36HlVJJSIk2Lxlmyd8+da1RBuew5Q2ckZbEhcuB6DAqYv7mjOZqmTBB60ZFcWGN1NHnnaGIR8bv0A27zV9R\/rWMX0bz\/cKpFwARVogJsSrNoY+FxpPp61ExfgkEaNmD7EHBz0qO+iUmyyBtUd2m+8eR8jVpaNE6Nf2etMdn0uI2yBIwkUc18j7GuDzcLa+qv6kSe6O8QYx2VxpJAZNJx5GuTBL76EbH+BjaOK8Q55azZPq6V6eGfHkawVs9Nbg6kk6Rv6Vk4I7ORW3BhjZKFCloHI86\/i9YfZLPhLacFp5Fzj+gUp6iY5n0ZaxbF26+div5b\/tWsXtfwYR\/cW3F9FZQa5W0g8gNy3oK05aOiUlHsznE+MXN6jRjMVudu7U7t7n9qjnydJnLKbnZ92c4Mb+71SnEK7uw5+w9a0i30XCHI3Hb7iMdt2MsuFWqLFFJODoQ4ACDP6kVvKX2NCkqZ6B\/wCGRo+HcI4lcS6R9qmAyf5UX+7Gq8ZXAU9M9q4jd27xB2lVFxzJroomxS09vIv3F2ur1G1LTGHWImljIIWQf0NVL8kkOK3dknAL\/wC3SiOCOMly\/wCHy+eaU2km5dC5cdn5p7QcTN7OUjBW3Q+FT\/8A7H1r4\/yczzSqPRTk5O2Z+4lP4Tjy9B1NVgwcnSJDezHD1vLr7XcD7iFvAp\/G\/r7frgV63FQXE6cOO\/uZsmm6k0HRREzA4waLCj4vv6UCZWXoAiX286AIl6AIa80ARL0CIF6AId4M7UDPi+1AHNYoA8UTGrA3xz32FdzMmw6BsAlufQKKlgTZmJyzAegpewLBIQoyAP1pOwPgcjmfEd89faivkV2DcRAeDb8P6U6rZM9oGQd5AoP8op7ox7Fc0ZjkK\/Sruyuwy1m1ov8AMPXn61jkhRLL3OTke9Yr4F7A7oeJWXkdq3xvVFKgYj02+lb+hny8vWkBKQ7bULQtlXUDJJByKr+R9B9oe8jmi6um3uNxWb7srtACnO\/nzqiWOLG5ls47WeBsOjsR5EbbH0rBtqVomSPR+G3sXErFbiHrs6nmjdQa3UuUTL9rMZ2ui0cfuumtI3H0A\/asUdU9sSCF5CRGupuZx\/vaqRm2TSExDOoMeW3IfPrUSq6EvkpuJDIxaRiTWi0UER97bMJYsZ3zkZBHrWfJXsXs1XBrtrForu2AktZF0Sxefmp\/Y1jklLFLk9xfZMqeg3jarHa3AjYmMqrIT1U4I\/I15sYKGZU9AjYfwG0Nx+eN2AaSBlTP4jkHH0B+ld8F2a4nvZ76toMDarOiz42Y8qKCzyX\/AMQcAi4XwH1upv8A\/mtZ5V9uzPK+jyo3Zsb+Gbu+8P2VVCHYHII39KTmocZP4Oe2mJp+8uLhpZ2LOenQD08qxeRzegbbdsgU1yhFHM4A6murGqjQLezbcNiS1tFiTmPiPUnrWyo61GlRnu21133ELeAHaOPJHqT\/AKCpySpGM9yPT+xF0\/CuztnGhx4NZwcHJOa68WopEscX3aeWZAC2P6WolMqMTsXG3jjDhic+vWkpaG42aLgHaaVXjCyE6j051ccpEofJi\/4kdsH43etHbtptFIGBt3rDbWf2rwPP8760uEP2r\/Uw72zz6WXGeuTv6muLFG6K7KrSzn4rxOCwtRqmmbBONlHMk+gGTXsY8axouMeTo9Li7NrbwJDCCERdIzz96iUHJ2z0IySSSIPwRxyFT9JlcyluCyjkCPajgw5orbhdyv4m2p1JByRU9hc5zk5ouQvtKntLpc7Z+VHKQUiox3I5pmnzYOKK2Mw5xmnzftC4fkrMjDmjD5U+aBwItN55FPkhcWV98uTg0KcX7BwZITDTvVCaaOd8KKEeQxAggKPeux9mX8BSLoG3M7Z9aQrOyA4IB5UUuwJKNKb7daTD2QaUE+HxHl7UDJCIzRPqJACk7Uu+xP8AbQFA3hXzx+9WjAjfQ6o9Q6dRRdMSYuhcxSA9Ad6qSsoYqwZfMHH0rmlGuyGVTLqBB59KqDpjQGTyroWyjm2fT0oA6eVHfYFB5j+9XtCDLOXTKjZ5Heokk9FohdRCK7kQcgdS+x3FJPVktbCsj7NEBn4mP6VjJbJb2M+BcTl4Zch1BaJvDImfiHp6j\/SlGfF2ZyGvamS2u+IxTwyiRWtlDBdiCCefltTk4p8jVu0hFJIFGnG3RRy+nWoTlN\/gnsFmkJIyTq\/lB\/U1rDHxRSVF\/DLSOacfaDsRgL5E8s1GXJ6X+ZLlXRORwtxJEwA07bjr5VnCL4KXscVoI4VefZZzHJvE2zKeVatKUd+x99Gj4nIJOHZXdREiAnrjFebkxSx5o\/FEhvY66msQLq1fu7iGRJI28mBOPl5+hNaSnwxuXw0K36P1T2d4lDxvgtpxG3AVZ0yUznQw2ZfkQRXZFKS5I6Yz5K0MhHmnxZVnjv8A4jAjWnZ+DWglE00mjPi06VGrHlnIz6Vz+S+ELZlkkeJypjOTlvU15fNzezHplGg59\/St06Qwzg1r3nG4x\/KQB7mu3xpckxof3UctuxBX0BrdaO7sxd05vePPv8UgUew2qO2crdys38XEBHFpz92Bp0+1dKkauGjq3xl2O\/r1qXL5KSoKS4ZogmfzrNvQUgi9vms7LuUY9\/MuTv8ACh6e5\/T3rzPO8lxX0ovbOfLPk+KMzLIXcnJNedGNIyA5HwNZPov7mvW8XDSUmB61\/CHss1vwZuMXUeLm\/H3OfwwA7H\/5EZ9gPOuyrOjGuKs3jcO9KfE05FbcOH8opcQsqbhw\/lpUOypuGjqgo4hyKn4an8lLigsqbhaH8IoodlD8JT+UUUg5MGk4Mh\/BS4oOQLLwVDnC0OCHyYFNwMb4UfSpcCuYBPwEb4U1Lxj5gE3AGBOARS4UVzA5OBzqfCTijiw5JnjyZCnR9a9CjlLY\/wCrljl5VLBMkAC3i5Z2\/wBaPQyMmFUk4LHlRQvZWrBXwCC370\/Q+g1MacasqowccqNpUxasVRjEYI6MaI\/kw9hUeHjYVTQhNdxd3KR0NVF+hlto+RpJO1ZzjewaCH3XbnWEVQkCSghs9PSulPRXZUcY5YPWqC\/RBj8t+lNAV8+tV0gLIDgkHf5+VS1oaDrwa44JRnYaCfbcVC1aCR3P3cY671nLT6IfdBMKYALE5\/SspzUfyxVZKSUhTpOAPPp70oQbdsE2wQszErGDnzro1EaJd3oHvSTsbYRbsQQcY3+tYzTZmzkzmfikhOPEwGfPYCqTaxo0j0cu4jDK6nmhx7iqhJNWCYx4bfZi+zzklG2z5etVOKkqYNGi4WrQWUwY7q6fqa87NGsckyXo9G7CdqpuDW1zbbvAxEygH4Tyb\/8AE1HiZWouPwaYX91P2aq4\/idDZ2jzSRSMyjwoCBrboM9K6X5HFWzoyRUFbPJONcVvOO8SuOI8Tl7y5m3OOSKOSqOijkK8nyPIeZ2zh7diWVRqJIqYOtjOLHgFj0q3LQwvhpaGdJI\/jDa\/oCa9Hx3xhQ4K5IYT8bbuXM8edKk59QK2jmXTO6UaTaMf2eUPxESycly5P+\/Wmr5I5YI0rzxbgyACtXJfJ0bPlv40X7oM7DpyqHkgvY+MmGcJe5mkkuroItpBzQHeRz8KfufT3rDN5axwcq\/gyzPgu9nLu5knlkeRizOcknrXhRubuT7OVAbtq8PInmfIeddeDH9WfH0P8jfsTwA9qu1Vrw86ls1+9uWH4YV5gerZCj1b0r2ox1r+Bw2z9RRwRKqpGERFAVVXYKAMAD0A2rTgb2dMA6AGjiwsi1uPKhoLK2tlPSlQWVNbL5UqCyprQeQo4jsqa0FJodlbWgzsBSoLK2sgelFBZU1gPKjiFlD8PB6U6FZQ\/DR0FKh2Dvwz+mhoaZQ3CgfwilQ7PyfCCzBRso\/Oulv0ZlwXG53xyFRQyvUCzH9Kar2BWzjGQNPl5mjsZ9Gm2o0l+QYSjFVAyNjvR2IHijzasdshjVLo5W90fWx8YH6VVWF2C8Ujzk43prTKi\/QsQlXBG2OdNq0MOVwyg7kHnWMoNCIt4iRj29KcGNFBBNaehlbjbmaBUUnz5flV2q2MkhIcHpRdgNIV721mTmVGtdvKsZadlNaslbx6iDnAArGToy12iyd9AycAVMIX2OgeMSXMgVBn9hXQ2oofSCUiWIYH1xzqG7TbEmccZ\/1o2B9EcEZ86ib9EHLMauIAZzmTf6051GKNfQx43HidXA55B+tcnizttL5ITFGSrDBr0OykzU8E4i09s9vJ8Zxg+eK5fIxuUGo9ikmaXg8+kxOTkA4YenI\/ka8jFP6eZW9PRCb7QBxK47+7YI2qKIkKR18zV+RK3xXSNcuR5GQZ9sVyJW7RmREZbA8\/Sqc6WhJEp1xpUUsbvYy+2XE8APJgw\/8AtNelgl6Lh+5AnaIiHhcm3ichB+\/5CtopWdud1GvkC7MQBo5nPooqpezHCt2Ovs4PQVFM6S+2sTNMkcSqXbYZ5DzJPkNzQ0TKXFWwq8lRRHb23\/p48hTyLHqx9\/0wK8fNm+rK10ujglLm+TF8p+LB2G1TBCB3JSEk83\/IV7XiYuMb9sT0ansbfycFtpZYiyTXGCxU48I5D9TW88lSpHXix\/bb9mpj7bX6HadtuhNT9R\/JpwDIv4gX6AeJWq1lol4wu3\/iXepnvURxn2xVrM\/YvpDGD+J0f\/Xtl+Rp\/WT7QvptDGD+I3C5B97G6Gn9WDFwkg2Dttwab\/q6fc01KD9i4y+A+LtFwqXlcp9aacX7FsITiXDpfguY8+9FJ+wtlyvbyDwSofY0+AciWhGzpdTj1pODDkcNuDvnPtRxY+RB7XNLiFlZtPSlxCyBtBnAHrRxCz8S2zMx8PLHOtG60OrO3D63zk7bUmBFsAeE7e9D+R0Vr4mJK89hnrQwLiWxgkeHypXWhHFByF9fpRaHXwX2q5jlU9GNVG2jjyfuoEde7lB5CrVgqZVekMh5Gjsa0xOw3J50\/RoWQSYBXcjnUTWgLiSGByNqSXoRyUdRVLYWVNyOBn3oQylhjNXsDhG\/z8qaJsZcOl0TIeh2I86ymkXaDIMLGzHYA+fKuWVuRC7ATmaXP4eldS+1DoY8JUC5VBndSPfauZtykmRZKQYZvLNa0BRKdsenWhDK4\/fkaUloTLeEjPEIs8tdKb0X6NHxO2zwu\/dxuksSqfcsT+WK4\/Gjx5P8mXbozEq+fyrsizQlaTPBMrAnwnNaP5HZtLabvLcNFsJRz8vOvF83DwnzXTIaBnbD6Ryrm9WBONu8k9AKX7UJbGES58XyFc0n6HeylzqlYjcCt8a0AZCpM0XoTz9jXZ48v7z+hcP3IRdr5d7WAern9B+9dsFqzfPLaiMOzkPd8MU4+Mk70MvCtWM9OMn86k2YYWFnaEHaeZfFnmqdB89ifTArg83PX91H+pxZp8nS6QsZttW+a89L0Ygjt3hVAfi5+1dvj4+c0v8AMZEA3FyF5L+gFe2nUXIeOPKVDgEjGk4A5VzHorRwsx65FJgR1t1NIZ0Ow6mqEfd4fOpHZ8JWA5n60xaPjK3nTt9ASW4lXGljn3othotXiE64Ac0chUXx8YuU+GWRf8rEVXKhcbC4u0nEVHhvbhfZzTU36YuK+A6DtjxaMjTfzfM5q1ll8k\/TQwg\/iBxZMargN7qBVrNL2S8aDov4i8RHxMhPquar6rF9MMj\/AIj3h5pAfXBp\/VYnjR+aVYImnHLnWtewsgrb5PPG3oKQzqgyHnSYj47HYY9BRQE48s7DpyNMC3c6ccyaljCbQeOUHnqqsZy5U+QLfR4XOOVXX9DOOxdK2qI+3nT9Fp7FhxnFBocGxyM0AEB9WN6zCy5BqAU8z51L0JlLppO3KtQKCPFzxtTT9AQ9frT0ARbtgA7bVL+RoYX0quESPYMoZwPPyrOMUvuBlWBGoX8R3P8AapnIzsYcI\/8AXRD5VlVNE2TuRiVs1rXyNOgaTGT546UIbKoviwfapmLvRdwbe\/iyR8Y\/WjI3o0ZsuLxj\/wArGQc5Jl1e6oR\/auTHJfS\/\/sZLUjHyLgeWD0raD2UmVtGDnG3pmnypaGnsd9nbnZ7ZjzGU361n5EPqwddrYWFXJ0OTXmQV9kvRdYjKZPNqjLpgM\/hT22rjqxsqhGpx710w6DoPt18S79CfyNb+LTyf0Lx\/uRju0Mvf8ckUZxHiMY9Of616KdKy8jubNfZR9zaQx\/yoKH2dMFUUHWka+KaUZih3IP4m\/Cvz6+gNZZcixwc2RmnxjrtgV3I0szMx1EnUSfM14btybfbOP8AUrbc+fX0rSNoKB9emJmz4nOBtyFez4mLhG12xBvC4dMRlOxfl7f7\/AErfI90jswRpcmGHNZHQtHxoaAjjHlSGfU+2L+Tm\/XpSA5+tAHDypgRPnmkB9nlSA+z60DIlsH3pbQvR8GP\/AGpptCJd565qrA73mPKnYqOiU\/zVXIKPOch+YOOZzXd7MT748joOZpNAXgaUOeQ2qf5BJkNyfnin\/Aei5E0kDz51PasC9Fy48sZpd9D9MItB\/wAxIMbEA\/tV4u2c2dU0yviafd7c61ZiuxBKcA5FBotgLc9\/qKCiHXPKnXsLLImwMEbc6mdAEIdxtvUMT2fSuBOVONLAfOnFa\/gEqRXNGVAIzpO2f2NNPY31ZSRk1evQycOc7HnSdNCsY2EJlmGQSoNZN\/ApSDuL2fdFZ4h922FYfyn\/AFFZNEIr4U2L+Ek7Bsc\/Ws5dp\/kEFcQXTcOD1rofYAMh3O1KhlcWdftUz+RMu4P\/AOtiwBjWDSyu6Lelo2N+S\/Z5k\/CsqyH5qy\/rivJwTbjOH5TJrZlHGV9xyrui9iIxjIGKTYdFkLm3uklXoc1pCVlDjiTDKld9W6+xrh4cZtEPsLshhVrkyOm6GGyHEZHrsa5ktjJW4wTjoK3tqLQBqEJlzsEQsfpW\/hq5t\/gvG\/vTMPw9TecUDNuZJNX1Nek\/SFFts3yxSNC8qIzRRnDOB4VzyyeQ+dJW+jvbS7YJNxu2biUPC7VBcQrG5kmDFfGQPGvmBjG\/QVl5OKDg3P11\/wAnFO5XNlMrZIzzx9K8NIz7A521HQB8XP0FdmDF9SSXoLIQobq4WNNk5ZHQdTXtJ8V\/sVCPJ0h6FAACjAAwBWPs9DRw0h9kTyoA+3xSYEdzzp\/yI+\/SgZ8fypICO9OgONyo2K6PgM4pd9gRIyKNAQI32pdMf8HBnlv8qAO5+lMCBOPOpYI+1elFgYAgsSBsBzNeozmLYkIwfOp7Y+iUh6bCgNklGSSM46UvwBei5O+221TYdF4XxCkxlq+CWNz0Ok+x\/wBcURlUkzLNHRPiK\/dZI+VdT62cj7Mvd+Fjil6NlQCaL2URPn6U+wPkJBBHL0oq9CCo89OfnWUq9g\/kruxlUYZ22qod0hWWW0oZDkDOMMp6inJcRshcRd2QR8LfCaItMVn0IywPlvihjRoeGwhEXP8AvNZpezKbt0xozR6jFMAYZfCwoaXRIllgaw4oInOcMCrY2YdDWE7iU6aC+LDFy3pWrYR1sXORgigq7K4RljvvUZNkvRbwkgXkR\/qHOjIVJ+zbhO94fcxDJ1QsR6lfEP0rw8Uv75r5AyPMA4xyr0V2T7IxEDAxz6U5Id\/JORdSHbaoTqVsEw\/WZbK1YndSUPy3\/eqzR3yBjK1OFHoM15mTsFsKkbKryzWMNvYwi1HnyzW0k1ED7i8hi4VdFN2dO7X1LED9K38Jdv0NOjO2Drw371AktzyUkZVT6D8R\/wB711SyO6iJSfou4rdXbw6r2ZmlI0xwgBQgPmBt5bVUZW1Gy7tl3Z7h720bzTgd7KPxcwv+tcXneQpf3cekEnehhcNgEmuKKvRFAUj4XOfG\/wCQr2vGxcY\/liG\/DLfuYAzDDvufQdBWs3bpHbhhxj+WF8\/SoNrs+35cxT6CzhFICLDNKgOAU6C\/k+0+dIZ8BzyKYrOEDpSAgQaAPhQHo+PI0UBAj6VLWwI48qdAiBGOVTuhkTnnSoZ0nbH71Viow0MbsdyNPWvSbOVljMAcDYCkUV7sdvrSbGrL0Q7DnjFJ9gqCVUY386kf5L1XxBuvSgRPuwyFTtqGKn0J77OvmW03+MbMPUV1QfKKZwyjxdGY4guCd6frRcBc3XGdjTRZDlv\/AK0AffP8qYBFu22Kzkq2DLZEDxsu3LIqE6EARv3MoIzzwRjpW\/4GxooEsbR5BDbqfX\/e1Y3TsllVohMmnGP2qpMZpLcYto2I3Y5oRhJ7LOJBjASvxKc0pKh3sCvbgT2lpIf8RCUPtWM1or2W8VbU6t0ZQfyoi7iqBWLWPh\/tVDsjBjXvjGc+dRkTYnpk+GnF0hP8wFPKrLl0b6zcLKmvkGwfY\/8AevnuXHIpP5JZjtGFxnYbV6a\/cSVRczvVzeqD8hIXOV5Cse0HQRZbwzRHcghx8uf5GtZSbhZemMrc+FjvvtXmTEgpz4gDms4bex\/gLthtv7860yriqYdi\/j9yS0drHnOe8b9AP1NdWGLjD8sl7F0Mi2xBTDTfzDcJ7evrWnB\/9pSTGPD+H65BdXW\/VVP6mufPnUF9PH37Y260g+V8KWbmf94rgUbYgCVu8c5PhXdvfyr0PEw8ny9IWyfDYTdXZd\/gTxMOnoK9RtxV+2bYocn+B8M5yayOw4OVAH2AKQEetFDsiw25bUgI5pgcJz51LA5k0D6O74qrEc96QHBjOOlCA+IpiImk0Mgd\/ejYEW26VIEcbYzTQzh+VDsRjB19K9FoworHiG\/TaperAvRAQOdEiqLYwPzNR10HwXY8WOmcUVphHZeo60pEouUDu9XUCnQ10QAxclR8Lrkj2OK0xKrOfyUtMz3F0A7zHQ1o9Myh8CZhhzVGtFZOR7UCPsU6saRKA7gdKTRD\/bYWjHAO2SM1g3cqBIBulCzHHma6I\/tQ2GWDExA53XlWeT4Bdh8CAGcjYhqn2JqkOjtbxkeVP8mJObxRnPWOrlH0THqzPTsRIF6fF86yn0zoroaXniit8nnGKyxK4maADuregrX3RbRyHZyOnP8AKs8j0Q\/ghZNi5XGPiqcm4lyN3GxB6dK+eybkwXRlzt9RXqNezJkYgPEPInFVOTuhlyDce9ZyVRsbYTZ\/+sQeZKn2IqoP0W\/kMtiQvzrhmTe6C23lXPv+dRhVvYxhb7Ln0q8\/oBDxQ4uJ3\/FJIyk+gwABXXi2khpFvA7eN3d3XUUGwPLnS8ybx4vt9lPSHcjFYwR1GTXkdEAMpyD6cq2hsPQEzHRGvQrrPqa93BFKCSJTtj\/hkSxWcenm41E+tOXbPRxpKKoKNQy0cbbFAM+HKgCP4aQIhS9lI4xwPlRLoSKzzx86TGdWmhHx5c6EBHng9aOxneYo9kncbUwI0ARB25CjoD7Gc0n7ArPMCkP0QO4pDR\/\/2Q==" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected-metadata.json new file mode 100644 index 000000000..a11bb0d5e --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Natus eaque totam provident obcaecati nisi praesentium iusto velit fuga debitis quidem ut repellat corrupti, eligendi inventore quibusdam perspiciatis delectus omnis pariatur excepturi quasi fugit? A adipisci natus nostrum, qui aperiam, at culpa corrupti autem enim earum vitae. Nostrum et officiis facere ex recusandae tenetur, delectus odit provident soluta id perferendis ducimus quibusdam corporis rerum voluptatem architecto sequi beatae quod mollitia voluptatibus earum tempora inventore ut. Deserunt reprehenderit recusandae nostrum, eaque fuga cum, repellat, perspiciatis ducimus in non consequatur ratione. Sint rerum necessitatibus deleniti odio earum voluptatum eos modi ab dolor minus.", + "Image": null, + "Title": "Document", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected.html new file mode 100644 index 000000000..9ed1e6256 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/expected.html @@ -0,0 +1,11 @@ +
+ Illustration for article titled The Spectacular Story Of Metroid +

Lorem ipsum dolor sit amet consectetur adipisicing elit. Natus eaque totam provident obcaecati nisi praesentium iusto velit fuga debitis quidem ut repellat corrupti, eligendi inventore quibusdam perspiciatis delectus omnis pariatur excepturi quasi fugit? A adipisci natus nostrum, qui aperiam, at culpa corrupti autem enim earum vitae. Nostrum et officiis facere ex recusandae tenetur, delectus odit provident soluta id perferendis ducimus quibusdam corporis rerum voluptatem architecto sequi beatae quod mollitia voluptatibus earum tempora inventore ut. Deserunt reprehenderit recusandae nostrum, eaque fuga cum, repellat, perspiciatis ducimus in non consequatur ratione. Sint rerum necessitatibus deleniti odio earum voluptatum eos modi ab dolor minus.

+ Illustration for article titled The Spectacular Story Of Metroid +

Quae veniam recusandae vel cupiditate doloribus pariatur, dolorum saepe hic quos mollitia harum nihil molestias magni modi maiores? Ea accusamus velit vel doloremque pariatur voluptate? Consequuntur dolorum fugit facere architecto eveniet beatae eligendi rerum nisi maxime, voluptatum a repellendus perferendis dolores eius repudiandae accusamus animi eum esse adipisci voluptatibus incidunt necessitatibus! Adipisci id, quos libero dolor odit dignissimos et, cum explicabo est facere aliquid mollitia! Iure nihil nobis beatae quibusdam, dolor saepe reiciendis, exercitationem hic accusamus quasi commodi modi molestiae ipsum, maxime non nesciunt deserunt itaque quo cupiditate rerum ipsa ad minus vel quod. Earum dolorum velit aut minus hic?

+ +

Quidem nam tempore ex harum repellat modi expedita quia rerum est ut ullam, quisquam repudiandae at dolorum. Sint atque fugit facere id blanditiis dolor omnis rem repudiandae, laboriosam unde delectus illo voluptate dolorem consectetur rerum expedita quas debitis deleniti iure amet. At sequi distinctio facere eaque, esse molestiae tenetur, unde sapiente fugit minus eos ex aperiam atque? Animi soluta, dolorem sequi doloremque pariatur in. Impedit, voluptates dolorem natus perspiciatis pariatur eligendi labore rerum facilis est error. Illum eveniet nostrum atque nobis molestiae expedita perferendis, esse ullam corrupti sit explicabo beatae. Sapiente aliquid nesciunt reiciendis incidunt cumque et officiis minus aliquam?

+ +

Veritatis sit nostrum officiis alias ea quam nulla veniam eos, quidem nisi, magni molestias ut odio. Ea, mollitia nesciunt. Maiores iste quos quas sapiente sit at esse quidem? Laboriosam fugiat nobis voluptatum reiciendis aliquam excepturi ipsum? Perspiciatis expedita sit quod, optio assumenda veritatis culpa, neque explicabo distinctio facere incidunt magnam accusamus, quidem animi delectus doloremque vel molestiae a quae dolorem. Sit, at? Numquam possimus animi esse incidunt quos quibusdam. Ab sit eligendi laborum beatae maxime suscipit, obcaecati enim cum nam autem, dicta nobis corrupti ut aut nostrum ex excepturi perferendis, soluta veniam. Excepturi beatae suscipit enim dignissimos! Quam, esse praesentium!

+ +
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/source.html new file mode 100644 index 000000000..4d5ccac5a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/data-url-image/source.html @@ -0,0 +1,19 @@ + + + + + + Document + + + Illustration for article titled The Spectacular Story Of Metroid +

Lorem ipsum dolor sit amet consectetur adipisicing elit. Natus eaque totam provident obcaecati nisi praesentium iusto velit fuga debitis quidem ut repellat corrupti, eligendi inventore quibusdam perspiciatis delectus omnis pariatur excepturi quasi fugit? A adipisci natus nostrum, qui aperiam, at culpa corrupti autem enim earum vitae. Nostrum et officiis facere ex recusandae tenetur, delectus odit provident soluta id perferendis ducimus quibusdam corporis rerum voluptatem architecto sequi beatae quod mollitia voluptatibus earum tempora inventore ut. Deserunt reprehenderit recusandae nostrum, eaque fuga cum, repellat, perspiciatis ducimus in non consequatur ratione. Sint rerum necessitatibus deleniti odio earum voluptatum eos modi ab dolor minus.

+ Illustration for article titled The Spectacular Story Of Metroid +

Quae veniam recusandae vel cupiditate doloribus pariatur, dolorum saepe hic quos mollitia harum nihil molestias magni modi maiores? Ea accusamus velit vel doloremque pariatur voluptate? Consequuntur dolorum fugit facere architecto eveniet beatae eligendi rerum nisi maxime, voluptatum a repellendus perferendis dolores eius repudiandae accusamus animi eum esse adipisci voluptatibus incidunt necessitatibus! Adipisci id, quos libero dolor odit dignissimos et, cum explicabo est facere aliquid mollitia! Iure nihil nobis beatae quibusdam, dolor saepe reiciendis, exercitationem hic accusamus quasi commodi modi molestiae ipsum, maxime non nesciunt deserunt itaque quo cupiditate rerum ipsa ad minus vel quod. Earum dolorum velit aut minus hic?

+ +

Quidem nam tempore ex harum repellat modi expedita quia rerum est ut ullam, quisquam repudiandae at dolorum. Sint atque fugit facere id blanditiis dolor omnis rem repudiandae, laboriosam unde delectus illo voluptate dolorem consectetur rerum expedita quas debitis deleniti iure amet. At sequi distinctio facere eaque, esse molestiae tenetur, unde sapiente fugit minus eos ex aperiam atque? Animi soluta, dolorem sequi doloremque pariatur in. Impedit, voluptates dolorem natus perspiciatis pariatur eligendi labore rerum facilis est error. Illum eveniet nostrum atque nobis molestiae expedita perferendis, esse ullam corrupti sit explicabo beatae. Sapiente aliquid nesciunt reiciendis incidunt cumque et officiis minus aliquam?

+ +

Veritatis sit nostrum officiis alias ea quam nulla veniam eos, quidem nisi, magni molestias ut odio. Ea, mollitia nesciunt. Maiores iste quos quas sapiente sit at esse quidem? Laboriosam fugiat nobis voluptatum reiciendis aliquam excepturi ipsum? Perspiciatis expedita sit quod, optio assumenda veritatis culpa, neque explicabo distinctio facere incidunt magnam accusamus, quidem animi delectus doloremque vel molestiae a quae dolorem. Sit, at? Numquam possimus animi esse incidunt quos quibusdam. Ab sit eligendi laborum beatae maxime suscipit, obcaecati enim cum nam autem, dicta nobis corrupti ut aut nostrum ex excepturi perferendis, soluta veniam. Excepturi beatae suscipit enim dignissimos! Quam, esse praesentium!

+ + + \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected-images.json new file mode 100644 index 000000000..9a202b58e --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected-images.json @@ -0,0 +1,5 @@ +[ + "https:\/\/aem.dropbox.com\/cms\/content\/dam\/dropbox\/tech-blog\/en-us\/2020\/11\/atf\/diagrams\/Techblog-ATF-Social.png", + "http:\/\/fakehost\/cms\/content\/dam\/dropbox\/tech-blog\/en-us\/2020\/11\/atf\/diagrams\/Techblog-ATF-720x844px-1.png", + "http:\/\/fakehost\/cms\/content\/dam\/dropbox\/tech-blog\/en-us\/2020\/11\/atf\/diagrams\/Techblog-ATF-720x225px-2.png" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected-metadata.json new file mode 100644 index 000000000..d3d991323 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Arun Sai Krishnan", + "Direction": null, + "Excerpt": "I joined Dropbox not long after graduating with a Master\u2019s degree in computer science. Aside from an internship, this was my first big-league engineering job. My team had already begun designing a critical internal service that most of our software would use: It would handle asynchronous computing requests behind the scenes, powering everything from dragging a file into a Dropbox folder to scheduling a marketing campaign.", + "Image": "https:\/\/aem.dropbox.com\/cms\/content\/dam\/dropbox\/tech-blog\/en-us\/2020\/11\/atf\/diagrams\/Techblog-ATF-Social.png", + "Title": "How we designed Dropbox\u2019s ATF - an async task framework", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected.html new file mode 100644 index 000000000..e15acfa48 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/expected.html @@ -0,0 +1,527 @@ +
+
+

+ I joined Dropbox not long after graduating with a Master’s degree in computer science. Aside from an internship, this was my first big-league engineering job. My team had already begun designing a critical internal service that most of our software would use: It would handle asynchronous computing requests behind the scenes, powering everything from dragging a file into a Dropbox folder to scheduling a marketing campaign. +

+

+ This Asynchronous Task Framework (ATF) would replace multiple bespoke async systems used by different engineering teams. It would reduce redundant development, incompatibilities, and reliance on legacy software. There were no open-source projects or buy-not-build solutions that worked well for our use case and scale, so we had to create our own. ATF is both an important and interesting challenge, though, so we were happy to design, build and deploy our own in-house service. +

+

+ ATF not only had to work well, it had to work well at scale: It would be a foundational building block of Dropbox infrastructure. It would need to handle 10,000 async tasks per second from the start, and be architected for future growth. It would need to support nearly 100 unique async task types from the start, again with room to grow. There were at least two dozen engineering teams that would want to use it for entirely different parts of our codebase, for many products and services.  +

+

+ As any engineer would, we Googled to see what other companies with mega-scale services had done to handle async tasks. We were disappointed to find little material published by engineers who built supersized async services. +

+

+ Now that ATF is deployed and currently serving 9,000 async tasks scheduled per second and in use by 28 engineering teams internally, we’re glad to fill that information gap. We’ve documented Dropbox ATF thoroughly, as a reference and guide for the engineering community seeking their own async solutions. +

+
+
+

+

+ Introduction +

+

+
+
+

+ Scheduling asynchronous tasks on-demand is a critical capability that powers many features and internal platforms at Dropbox. Async Task Framework (ATF) is the infrastructural system that supports this capability at Dropbox through a callback-based architecture. ATF enables developers to define callbacks, and schedule tasks that execute against these pre-defined callbacks. +

+

+ Since its introduction over a year ago, ATF has gone on to become an important building block in the Dropbox infrastructure, used by nearly 30 internal teams across our codebase. It currently supports 100+ use cases which require either immediate or delayed task scheduling.  +

+
+
+

+

+ Glossary +

+

+
+
+

+ Some basic terms repeatedly used in this post, defined as used in the context of this discussion. +

+

+ Lambda: A callback implementing business logic. +

+

+ Task: Unit of execution of a lambda. Each asynchronous job scheduled with ATF is a task. +

+

+ Collection: A labeled subset of tasks belonging to a lambda. If send email is implemented as a lambda, then password reset email and marketing email would be collections. +

+

+  Priority: Labels defining priority of execution of tasks within a lambda.  +

+
+
+

+

+ Features +

+

+
+
+

+ Task scheduling
+ Clients can schedule tasks to execute at a specified time. Tasks can be scheduled for immediate execution, or delayed to fit the use case. +

+

+ Priority based execution
+ Tasks should be associated with a priority. Tasks with higher priority should get executed before tasks with a lower priority once they are ready for execution. +

+

+ Task gating
+ ATF enables the the gating of tasks based on lambda, or a subset of tasks on a lambda based on collection. Tasks can be gated to be completely dropped or paused until a suitable time for execution. +

+

+ Track task status
+ Clients can query the status of a scheduled task. +

+
+
+

+

+ System guarantees +

+

+
+
+

+ At-least once task execution
The ATF system guarantees that a task is executed at least once after being scheduled. Execution is said to be complete once the user-defined callback signals task completion to the ATF system. +

+

+ No concurrent task execution
The ATF system guarantees that at most one instance of a task will be actively executing at any given in point. This helps users write their callbacks without designing for concurrent execution of the same task from different locations. +

+

+ Isolation
Tasks in a given lambda are isolated from the tasks in other lambdas. This isolation spans across several dimensions, including worker capacity for task execution and resource use for task scheduling. Tasks on the same lambda but different priority levels are also isolated in their resource use for task scheduling. +

+

+ Delivery latency
95% of tasks begin execution within five seconds from their scheduled execution time. +

+

+ High availability for task scheduling
The ATF service is 99.9% available to accept task scheduling requests from any client. +

+
+
+

+

+ Lambda requirements +

+

+
+
+

+ Following are some restrictions we place on the callback logic (lambda): +

+

+ Idempotence
+ A single task on a lambda can be executed multiple times within the ATF system. Developers should ensure that their lambda logic and correctness of task execution in clients are not affected by this. +

+

+ Resiliency
+ Worker processes which execute tasks might die at any point during task execution. ATF retries abruptly interrupted tasks, which could also be retried on different hosts. Lambda owners must design their lambdas such that retries on different hosts do not affect lambda correctness. +

+

+ Terminal state handling
ATF retries tasks until they are signaled to be complete from the lambda logic. Client code can mark a task as successfully completed, fatally terminated, or retriable. It is critical that lambda owners design clients to signal task completion appropriately to avoid misbehavior such as infinite retries.  +

+
+
+

+

+ Architecture +

+

+
+
+
+ Async Task Framework (ATF) [Fig 1] +
+ Async Task Framework (ATF) [Fig 1] +
+
+
+
+

+ In this section, we describe the high-level architecture of ATF and give brief description of its different components. (See Fig. 1 above.) In this section, we describe the high-level architecture of ATF and give brief description of its different components. (See Fig. 1 above.) Dropbox uses gRPC for remote calls and our in-house Edgestore to store tasks. +

+

+ ATF consists of the following components:  +

+
    +
  • Frontend +
  • +
  • Task Store +
  • +
  • Store Consumer +
  • +
  • Queue +
  • +
  • Controller +
  • +
  • Executor +
  • +
  • Heartbeat and Status Controller (HSC)
    +
  • +
+

+ Frontend
+ This is the service that schedules requests via an RPC interface. The frontend accepts RPC requests from clients and schedules tasks by interacting with ATF’s task store described below.

+

+

+ Task Store
ATF tasks are stored in and triggered from the task store. The task store could be any generic data store with indexed querying capability. In ATF’s case, We use our in-house metadata store Edgestore to power the task store. More details can be found in the Data Model section below. +

+

+ Store Consumer
The Store Consumer is a service that periodically polls the task store to find tasks that are ready for execution and pushes them onto the right queues, as described in the queue section below. These could be tasks that are newly ready for execution, or older tasks that are ready for execution again because they either failed in a retriable way on execution, or were dropped elsewhere within the ATF system.  +

+

+ Below is a simple walkthrough of the Store Consumer’s function:  +

+
+
+
repeat every second:
+  1. poll tasks ready for execution from task store
+  2. push tasks onto the right queues
+  3. update task statuses
+
+
+

+ The Store Consumer polls tasks that failed in earlier execution attempts. This helps with the at-least-once guarantee that the ATF system provides. More details on how the Store Consumer polls new and previously failed tasks is presented in the Lifecycle of a task section below. +

+

+ Queue
ATF uses AWS Simple Queue Service (SQS) to queue tasks internally. These queues act as a buffer between the Store Consumer and Controllers (described below). Each <lambda, priority>  pair gets a dedicated SQS queue. The total number of SQS queues used by ATF is #lambdas x #priorities. +

+

+ Controller
Worker hosts are physical hosts dedicated for task execution. Each worker host has one controller process responsible for polling tasks from SQS queues in a background thread, and then pushing them onto process local buffered queues. The Controller is only aware of the lambdas it is serving and thus polls only the limited set of necessary queues.  +

+

+ The Controller serves tasks from its process local queue as a response to NextWork RPCs. This is the layer where execution level task prioritization occurs. The Controller has different process level queues for tasks of different priorities and can thus prioritize tasks in response to NextWork RPCs. +

+

+ Executor
The Executor is a process with multiple threads, responsible for the actual task execution. Each thread within an Executor process follows this simple loop: +

+
+
+
while True:
+  w = get_next_work()
+  do_work(w)
+
+
+

+ Each worker host has a single Controller process and multiple executor processes. Both the Controller and Executors work in a “pull” model, in which active loops continuously long-poll for new work to be done. +

+

+ Heartbeat and Status Controller (HSC)
+ The HSC serves RPCs for claiming a task for execution (ClaimTask), setting task status after execution (SetResults) and heartbeats during task execution (Heartbeat). ClaimTask requests originate from the Controllers in response to NextWork requests. Heartbeat and SetResults requests originate from executor processes during and after task execution. The HSC interacts with the task store to update the task status on the kind of request it receives. +

+
+
+

+

+ Data model +

+

+
+
+

+ ATF uses our in-house metadata store, Edgestore, as a task store. Edgestore objects can be Entities or Associations (assoc), each of which can have user-defined attributes. Associations are used to represent relationships between entities. Edgestore supports indexing only on attributes of associations. +

+

+ Based on this design, we have two kinds of ATF-related objects in Edgestore. The ATF association stores scheduling information, such as the next scheduled timestamp at which the Store Consumer should poll a given task (either for the first time or for a retry). The ATF entity stores all task related information that is used to track the task state and payload for task execution. We query on associations from the Store Consumer in a pull model to pick up tasks ready for execution. +

+
+
+

+

+ Lifecycle of a task +

+

+
+
+
    +
  1. Client performs a Schedule RPC call to Frontend with task information, including execution time.  +
  2. +
  3. Frontend creates Edgestore entity and assoc for the task.  +
  4. +
  5. When it is time to process the task, Store Consumer pulls the task from Edgestore and pushes it to a related SQS queue.  +
  6. +
  7. + Executor makes NextWork RPC call to Controller, which pulls tasks from the SQS queue, makes a ClaimTask RPC to the HSC and then returns the task to the Executor.  +
  8. +
  9. + Executor invokes the callback for the task. While processing, Executor performs Heartbeat RPC calls to Heartbeat and Status Controller (HSC). Once processing is done, Executor performs TaskStatus RPC call to HSC.  +
  10. +
  11. Upon getting Heartbeat and TaskStatus RPC calls, HSC updates the Edgestore entity and assoc. +
  12. +
+

+ Every state update in the lifecycle of a task is accompanied by an update to the next trigger timestamp in the assoc. This ensures that the Store Consumer pulls the task again if there is no change in state of the task within the next trigger timestamp. This helps ATF achieve its at-least-once delivery guarantee by ensuring that no task is dropped. +

+

+ Following are the task entity and association states in ATF and their corresponding timestamp updates: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ Entity status +

+
+

+ Assoc status +

+
+

+ next trigger timestamp in Assoc +

+
+

+ Comment +

+
+

+ new +

+
+

+ new +

+
+

+ scheduled_timestamp of the task +

+
+

+ Pick up new tasks that are ready.  +

+
+

+ enqueued +

+
+

+ started +

+
+

+ enqueued_timestamp + enqueue_timeout +

+
+

+ Re-enqueue task if it has been in enqueued state for too long. This can happen if the queue loses data or the controller goes down after polling the queue and before the task is claimed. +

+
+

+ claimed +

+
+

+ started +

+
+

+ claimed_timestamp + claim_timeout +

+
+

+ Re-enqueue if task is claimed but never transfered to processing. This can happen if Controller is down after claiming a task. Task status is changed to enqueued after re-enqueue. +

+
+

+ processing +

+
+

+ started +

+
+

+ heartbeat_timestamp + heartbeat_timeout` +

+
+

+ Re-enqueue if task hasn’t sent heartbeat for too long. This can happen if Executor is down. Task status is changed to enqueued after re-enqueue.  +

+
+

+ retriable failure +

+
+

+ started +

+
+

+ compute next_timestamp according to backoff logic +

+
+

+ Exponential backoff for tasks with retriable failure.  +

+
+

+ success +

+
+

+ completed +

+
+

+ N/A +

+
+ +
+

+ fatal_failure +

+
+

+ completed +

+
+

+ N/A +

+
+ +
+

+ The store consumer polls for tasks based on the following query: +

+

+ assoc_status= && next_timestamp<=time.now()
+

+

+ Below is the state machine that defines task state transitions: 
+

+
+
+
+ Task State Transitions [Fig 2] +
+
+
+

+

+ Achieving guarantees +

+

+
+
+

+ At-least-once task execution
At-least-once execution is guaranteed in ATF by retrying a task until it completes execution (which is signaled by a Success or a FatalFailure state). All ATF system errors are implicitly considered retriable failures, and lambda owners have an option of marking tasks with a RetriableFailure state. Tasks might be dropped from the ATF execution pipeline in different parts of the system through transient RPC failures and failures on dependencies like Edgestore or SQS. These transient failures at different parts of the system do not affect the at-least-once guarantee, though, because of the system of timeouts and re-polling from Store Consumer. +

+

+ No concurrent task execution
Concurrent task execution is avoided through a combination of two methods in ATF. First, tasks are explicitly claimed through an exclusive task state (Claimed) before starting execution. Once the task execution is complete, the task status is updated to one of Success, FatalFailure or RetriableFailure. A task can be claimed only if its existing task state is Enqueued (retried tasks go to the Enqueued state as well once they are re-pushed onto SQS). +

+

+ However, there might be situations where once a long running task starts execution, its heartbeats might fail repeatedly yet the task execution continues. ATF would retry this task by polling it from the store consumer because the heartbeat timeouts would’ve expired. This task can then be claimed by another worker and lead to concurrent execution. 
+

+

+ To avoid this situation, there is a termination logic in the Executor processes whereby an Executor process terminates itself as soon as three consecutive heartbeat calls fail. Each heartbeat timeout is large enough to eclipse three consecutive heartbeat failures. This ensures that the Store Consumer cannot pull such tasks before the termination logic ends them—the second method that helps achieve this guarantee. +

+

+ Isolation
Isolation of lambdas is achieved through dedicated worker clusters, dedicated queues, and dedicated per-lambda scheduling quotas. In addition, isolation across different priorities within the same lambda is likewise achieved through dedicated queues and scheduling bandwidth. +

+

+ Delivery latency
ATF use cases do not require ultra-low task delivery latencies. Task delivery latencies on the order of a couple of seconds are acceptable. Tasks ready for execution are periodically polled by the Store Consumer and this period of polling largely controls the task delivery latency. Using this as a tuning lever, ATF can achieve different delivery latencies as required. Increasing poll frequency reduces task delivery latency and vice versa. Currently, we have calibrated ATF to poll for ready tasks once every two seconds. +

+
+
+

+

+ Ownership model +

+

+
+

+ ATF is designed to be a self-serve framework for developers at Dropbox. The design is very intentional in driving an ownership model where lambda owners own all aspects of their lambdas’ operations. To promote this, all lambda worker clusters are owned by the lambda owners. They have full control over operations on these clusters, including code deployments and capacity management. Each executor process is bound to one lambda. Owners have the option of deploying multiple lambdas on their worker clusters simply by spawning new executor processes on their hosts. +

+
+

+

+ Extending ATF +

+

+
+
+

+ As described above, ATF provides an infrastructural building block for scheduling asynchronous tasks. With this foundation established, ATF can be extended to support more generic use cases and provide more features as a framework. Following are some examples of what could be built as an extension to ATF.  +

+

+ Periodic task execution
Currently, ATF is a system for one-time task scheduling. Building support for periodic task execution as an extension to this framework would be useful in unlocking new capabilities for our clients. +

+

+ Better support for task chaining
Currently, it is possible to chain tasks on ATF by scheduling a task onto ATF that then schedules other tasks onto ATF during its execution. Although it is possible to do this in the current ATF setup, visibility and control on this chaining is absent at the framework level. Another natural extension here would be to better support task chaining through framework-level visibility and control, to make this use case a first class concept in the ATF model. +

+

+ Dead letter queues for misbehaving tasks
One common source of maintenance overhead we observe on ATF is that some tasks get stuck in infinite retry loops due to occasional bugs in lambda logic. This requires manual intervention from the ATF framework owners in some cases where there are a large number of tasks stuck in such loops, occupying a lot of the scheduling bandwidth in the system. Typical manual actions in response to such a situation include pausing execution of the lambdas with misbehaving tasks, or dropping them outright. +

+

+ One way to reduce this operational overhead and provide an easy interface for lambda owners to recover from such incidents would be to create dead letter queues filled with such misbehaving tasks. The ATF framework could impose a maximum number of retries before tasks are pushed onto the dead letter queue. We could create and expose tools that make it easy to reschedule tasks from the dead letter queue back into the ATF system, once the associated lambda bugs are fixed.
+

+
+
+

+

+ Conclusion +

+

+
+

+ We hope this post helps engineers elsewhere to develop better async task frameworks of their own. Many thanks to everyone who worked on this project: Anirudh Jayakumar, Deepak Gupta, Dmitry Kopytkov, Koundinya Muppalla, Peng Kang, Rajiv Desai, Ryan Armstrong, Steve Rodrigues, Thomissa Comellas, Xiaonan Zhang and Yuhuan Du.
+   +

+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/source.html new file mode 100644 index 000000000..83f2b05bc --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/dropbox-blog/source.html @@ -0,0 +1,868 @@ + + + + + + How we designed Dropbox ATF: an async task framework - Dropbox + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + +
+
+
+
+
+ +
+
+

+ How we designed Dropbox ATF: an async task framework +

+
+ // By Arun Sai Krishnan • Nov 11, 2020 +
+
+
+
+
+
+
+
+
+ +
+
+
+

+ I joined Dropbox not long after graduating with a Master’s degree in computer science. Aside from an internship, this was my first big-league engineering job. My team had already begun designing a critical internal service that most of our software would use: It would handle asynchronous computing requests behind the scenes, powering everything from dragging a file into a Dropbox folder to scheduling a marketing campaign. +

+

+ This Asynchronous Task Framework (ATF) would replace multiple bespoke async systems used by different engineering teams. It would reduce redundant development, incompatibilities, and reliance on legacy software. There were no open-source projects or buy-not-build solutions that worked well for our use case and scale, so we had to create our own. ATF is both an important and interesting challenge, though, so we were happy to design, build and deploy our own in-house service. +

+

+ ATF not only had to work well, it had to work well at scale: It would be a foundational building block of Dropbox infrastructure. It would need to handle 10,000 async tasks per second from the start, and be architected for future growth. It would need to support nearly 100 unique async task types from the start, again with room to grow. There were at least two dozen engineering teams that would want to use it for entirely different parts of our codebase, for many products and services.  +

+

+ As any engineer would, we Googled to see what other companies with mega-scale services had done to handle async tasks. We were disappointed to find little material published by engineers who built supersized async services. +

+

+ Now that ATF is deployed and currently serving 9,000 async tasks scheduled per second and in use by 28 engineering teams internally, we’re glad to fill that information gap. We’ve documented Dropbox ATF thoroughly, as a reference and guide for the engineering community seeking their own async solutions. +

+
+
+
+

+ Introduction +

+
+
+
+

+ Scheduling asynchronous tasks on-demand is a critical capability that powers many features and internal platforms at Dropbox. Async Task Framework (ATF) is the infrastructural system that supports this capability at Dropbox through a callback-based architecture. ATF enables developers to define callbacks, and schedule tasks that execute against these pre-defined callbacks. +

+

+ Since its introduction over a year ago, ATF has gone on to become an important building block in the Dropbox infrastructure, used by nearly 30 internal teams across our codebase. It currently supports 100+ use cases which require either immediate or delayed task scheduling.  +

+
+
+
+

+ Glossary +

+
+
+
+

+ Some basic terms repeatedly used in this post, defined as used in the context of this discussion. +

+

+ Lambda: A callback implementing business logic. +

+

+ Task: Unit of execution of a lambda. Each asynchronous job scheduled with ATF is a task. +

+

+ Collection: A labeled subset of tasks belonging to a lambda. If send email is implemented as a lambda, then password reset email and marketing email would be collections. +

+

+  Priority: Labels defining priority of execution of tasks within a lambda.  +

+
+
+
+

+ Features +

+
+
+
+

+ Task scheduling
+ Clients can schedule tasks to execute at a specified time. Tasks can be scheduled for immediate execution, or delayed to fit the use case. +

+

+ Priority based execution
+ Tasks should be associated with a priority. Tasks with higher priority should get executed before tasks with a lower priority once they are ready for execution. +

+

+ Task gating
+ ATF enables the the gating of tasks based on lambda, or a subset of tasks on a lambda based on collection. Tasks can be gated to be completely dropped or paused until a suitable time for execution. +

+

+ Track task status
+ Clients can query the status of a scheduled task. +

+
+
+
+

+ System guarantees +

+
+
+
+

+ At-least once task execution
The ATF system guarantees that a task is executed at least once after being scheduled. Execution is said to be complete once the user-defined callback signals task completion to the ATF system. +

+

+ No concurrent task execution
The ATF system guarantees that at most one instance of a task will be actively executing at any given in point. This helps users write their callbacks without designing for concurrent execution of the same task from different locations. +

+

+ Isolation
Tasks in a given lambda are isolated from the tasks in other lambdas. This isolation spans across several dimensions, including worker capacity for task execution and resource use for task scheduling. Tasks on the same lambda but different priority levels are also isolated in their resource use for task scheduling. +

+

+ Delivery latency
95% of tasks begin execution within five seconds from their scheduled execution time. +

+

+ High availability for task scheduling
The ATF service is 99.9% available to accept task scheduling requests from any client. +

+
+
+
+

+ Lambda requirements +

+
+
+
+

+ Following are some restrictions we place on the callback logic (lambda): +

+

+ Idempotence
+ A single task on a lambda can be executed multiple times within the ATF system. Developers should ensure that their lambda logic and correctness of task execution in clients are not affected by this. +

+

+ Resiliency
+ Worker processes which execute tasks might die at any point during task execution. ATF retries abruptly interrupted tasks, which could also be retried on different hosts. Lambda owners must design their lambdas such that retries on different hosts do not affect lambda correctness. +

+

+ Terminal state handling
ATF retries tasks until they are signaled to be complete from the lambda logic. Client code can mark a task as successfully completed, fatally terminated, or retriable. It is critical that lambda owners design clients to signal task completion appropriately to avoid misbehavior such as infinite retries.  +

+
+
+
+

+ Architecture +

+
+
+
+
+
+ Async Task Framework (ATF) [Fig 1] +
+ Async Task Framework (ATF) [Fig 1] +
+
+
+
+
+

+ In this section, we describe the high-level architecture of ATF and give brief description of its different components. (See Fig. 1 above.) In this section, we describe the high-level architecture of ATF and give brief description of its different components. (See Fig. 1 above.) Dropbox uses gRPC for remote calls and our in-house Edgestore to store tasks. +

+

+ ATF consists of the following components:  +

+
    +
  • Frontend +
  • +
  • Task Store +
  • +
  • Store Consumer +
  • +
  • Queue +
  • +
  • Controller +
  • +
  • Executor +
  • +
  • Heartbeat and Status Controller (HSC)
    +
  • +
+

+ Frontend
+ This is the service that schedules requests via an RPC interface. The frontend accepts RPC requests from clients and schedules tasks by interacting with ATF’s task store described below.

+

+

+ Task Store
ATF tasks are stored in and triggered from the task store. The task store could be any generic data store with indexed querying capability. In ATF’s case, We use our in-house metadata store Edgestore to power the task store. More details can be found in the Data Model section below. +

+

+ Store Consumer
The Store Consumer is a service that periodically polls the task store to find tasks that are ready for execution and pushes them onto the right queues, as described in the queue section below. These could be tasks that are newly ready for execution, or older tasks that are ready for execution again because they either failed in a retriable way on execution, or were dropped elsewhere within the ATF system.  +

+

+ Below is a simple walkthrough of the Store Consumer’s function:  +

+
+
+ +
repeat every second:
+  1. poll tasks ready for execution from task store
+  2. push tasks onto the right queues
+  3. update task statuses
+
+
+

+ The Store Consumer polls tasks that failed in earlier execution attempts. This helps with the at-least-once guarantee that the ATF system provides. More details on how the Store Consumer polls new and previously failed tasks is presented in the Lifecycle of a task section below. +

+

+ Queue
ATF uses AWS Simple Queue Service (SQS) to queue tasks internally. These queues act as a buffer between the Store Consumer and Controllers (described below). Each <lambda, priority>  pair gets a dedicated SQS queue. The total number of SQS queues used by ATF is #lambdas x #priorities. +

+

+ Controller
Worker hosts are physical hosts dedicated for task execution. Each worker host has one controller process responsible for polling tasks from SQS queues in a background thread, and then pushing them onto process local buffered queues. The Controller is only aware of the lambdas it is serving and thus polls only the limited set of necessary queues.  +

+

+ The Controller serves tasks from its process local queue as a response to NextWork RPCs. This is the layer where execution level task prioritization occurs. The Controller has different process level queues for tasks of different priorities and can thus prioritize tasks in response to NextWork RPCs. +

+

+ Executor
The Executor is a process with multiple threads, responsible for the actual task execution. Each thread within an Executor process follows this simple loop: +

+
+
+ +
while True:
+  w = get_next_work()
+  do_work(w)
+
+
+

+ Each worker host has a single Controller process and multiple executor processes. Both the Controller and Executors work in a “pull” model, in which active loops continuously long-poll for new work to be done. +

+

+ Heartbeat and Status Controller (HSC)
+ The HSC serves RPCs for claiming a task for execution (ClaimTask), setting task status after execution (SetResults) and heartbeats during task execution (Heartbeat). ClaimTask requests originate from the Controllers in response to NextWork requests. Heartbeat and SetResults requests originate from executor processes during and after task execution. The HSC interacts with the task store to update the task status on the kind of request it receives. +

+
+
+
+

+ Data model +

+
+
+
+

+ ATF uses our in-house metadata store, Edgestore, as a task store. Edgestore objects can be Entities or Associations (assoc), each of which can have user-defined attributes. Associations are used to represent relationships between entities. Edgestore supports indexing only on attributes of associations. +

+

+ Based on this design, we have two kinds of ATF-related objects in Edgestore. The ATF association stores scheduling information, such as the next scheduled timestamp at which the Store Consumer should poll a given task (either for the first time or for a retry). The ATF entity stores all task related information that is used to track the task state and payload for task execution. We query on associations from the Store Consumer in a pull model to pick up tasks ready for execution. +

+
+
+
+

+ Lifecycle of a task +

+
+
+
+
    +
  1. Client performs a Schedule RPC call to Frontend with task information, including execution time.  +
  2. +
  3. Frontend creates Edgestore entity and assoc for the task.  +
  4. +
  5. When it is time to process the task, Store Consumer pulls the task from Edgestore and pushes it to a related SQS queue.  +
  6. +
  7. + Executor makes NextWork RPC call to Controller, which pulls tasks from the SQS queue, makes a ClaimTask RPC to the HSC and then returns the task to the Executor.  +
  8. +
  9. + Executor invokes the callback for the task. While processing, Executor performs Heartbeat RPC calls to Heartbeat and Status Controller (HSC). Once processing is done, Executor performs TaskStatus RPC call to HSC.  +
  10. +
  11. Upon getting Heartbeat and TaskStatus RPC calls, HSC updates the Edgestore entity and assoc. +
  12. +
+

+ Every state update in the lifecycle of a task is accompanied by an update to the next trigger timestamp in the assoc. This ensures that the Store Consumer pulls the task again if there is no change in state of the task within the next trigger timestamp. This helps ATF achieve its at-least-once delivery guarantee by ensuring that no task is dropped. +

+

+ Following are the task entity and association states in ATF and their corresponding timestamp updates: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ Entity status +

+
+

+ Assoc status +

+
+

+ next trigger timestamp in Assoc +

+
+

+ Comment +

+
+

+ new +

+
+

+ new +

+
+

+ scheduled_timestamp of the task +

+
+

+ Pick up new tasks that are ready.  +

+
+

+ enqueued +

+
+

+ started +

+
+

+ enqueued_timestamp + enqueue_timeout +

+
+

+ Re-enqueue task if it has been in enqueued state for too long. This can happen if the queue loses data or the controller goes down after polling the queue and before the task is claimed. +

+
+

+ claimed +

+
+

+ started +

+
+

+ claimed_timestamp + claim_timeout +

+
+

+ Re-enqueue if task is claimed but never transfered to processing. This can happen if Controller is down after claiming a task. Task status is changed to enqueued after re-enqueue. +

+
+

+ processing +

+
+

+ started +

+
+

+ heartbeat_timestamp + heartbeat_timeout` +

+
+

+ Re-enqueue if task hasn’t sent heartbeat for too long. This can happen if Executor is down. Task status is changed to enqueued after re-enqueue.  +

+
+

+ retriable failure +

+
+

+ started +

+
+

+ compute next_timestamp according to backoff logic +

+
+

+ Exponential backoff for tasks with retriable failure.  +

+
+

+ success +

+
+

+ completed +

+
+

+ N/A +

+
+

+   +

+
+

+ fatal_failure +

+
+

+ completed +

+
+

+ N/A +

+
+

+   +

+
+

+ The store consumer polls for tasks based on the following query: +

+

+ assoc_status= && next_timestamp<=time.now()
+

+

+ Below is the state machine that defines task state transitions: 
+

+
+
+
+
+ Task State Transitions [Fig 2] +
+
+
+
+
+

+ Achieving guarantees +

+
+
+
+

+ At-least-once task execution
At-least-once execution is guaranteed in ATF by retrying a task until it completes execution (which is signaled by a Success or a FatalFailure state). All ATF system errors are implicitly considered retriable failures, and lambda owners have an option of marking tasks with a RetriableFailure state. Tasks might be dropped from the ATF execution pipeline in different parts of the system through transient RPC failures and failures on dependencies like Edgestore or SQS. These transient failures at different parts of the system do not affect the at-least-once guarantee, though, because of the system of timeouts and re-polling from Store Consumer. +

+

+ No concurrent task execution
Concurrent task execution is avoided through a combination of two methods in ATF. First, tasks are explicitly claimed through an exclusive task state (Claimed) before starting execution. Once the task execution is complete, the task status is updated to one of Success, FatalFailure or RetriableFailure. A task can be claimed only if its existing task state is Enqueued (retried tasks go to the Enqueued state as well once they are re-pushed onto SQS). +

+

+ However, there might be situations where once a long running task starts execution, its heartbeats might fail repeatedly yet the task execution continues. ATF would retry this task by polling it from the store consumer because the heartbeat timeouts would’ve expired. This task can then be claimed by another worker and lead to concurrent execution. 
+

+

+ To avoid this situation, there is a termination logic in the Executor processes whereby an Executor process terminates itself as soon as three consecutive heartbeat calls fail. Each heartbeat timeout is large enough to eclipse three consecutive heartbeat failures. This ensures that the Store Consumer cannot pull such tasks before the termination logic ends them—the second method that helps achieve this guarantee. +

+

+ Isolation
Isolation of lambdas is achieved through dedicated worker clusters, dedicated queues, and dedicated per-lambda scheduling quotas. In addition, isolation across different priorities within the same lambda is likewise achieved through dedicated queues and scheduling bandwidth. +

+

+ Delivery latency
ATF use cases do not require ultra-low task delivery latencies. Task delivery latencies on the order of a couple of seconds are acceptable. Tasks ready for execution are periodically polled by the Store Consumer and this period of polling largely controls the task delivery latency. Using this as a tuning lever, ATF can achieve different delivery latencies as required. Increasing poll frequency reduces task delivery latency and vice versa. Currently, we have calibrated ATF to poll for ready tasks once every two seconds. +

+
+
+
+

+ Ownership model +

+
+
+
+

+ ATF is designed to be a self-serve framework for developers at Dropbox. The design is very intentional in driving an ownership model where lambda owners own all aspects of their lambdas’ operations. To promote this, all lambda worker clusters are owned by the lambda owners. They have full control over operations on these clusters, including code deployments and capacity management. Each executor process is bound to one lambda. Owners have the option of deploying multiple lambdas on their worker clusters simply by spawning new executor processes on their hosts. +

+
+
+
+

+ Extending ATF +

+
+
+
+

+ As described above, ATF provides an infrastructural building block for scheduling asynchronous tasks. With this foundation established, ATF can be extended to support more generic use cases and provide more features as a framework. Following are some examples of what could be built as an extension to ATF.  +

+

+ Periodic task execution
Currently, ATF is a system for one-time task scheduling. Building support for periodic task execution as an extension to this framework would be useful in unlocking new capabilities for our clients. +

+

+ Better support for task chaining
Currently, it is possible to chain tasks on ATF by scheduling a task onto ATF that then schedules other tasks onto ATF during its execution. Although it is possible to do this in the current ATF setup, visibility and control on this chaining is absent at the framework level. Another natural extension here would be to better support task chaining through framework-level visibility and control, to make this use case a first class concept in the ATF model. +

+

+ Dead letter queues for misbehaving tasks
One common source of maintenance overhead we observe on ATF is that some tasks get stuck in infinite retry loops due to occasional bugs in lambda logic. This requires manual intervention from the ATF framework owners in some cases where there are a large number of tasks stuck in such loops, occupying a lot of the scheduling bandwidth in the system. Typical manual actions in response to such a situation include pausing execution of the lambdas with misbehaving tasks, or dropping them outright. +

+

+ One way to reduce this operational overhead and provide an easy interface for lambda owners to recover from such incidents would be to create dead letter queues filled with such misbehaving tasks. The ATF framework could impose a maximum number of retries before tasks are pushed onto the dead letter queue. We could create and expose tools that make it easy to reschedule tasks from the dead letter queue back into the ATF system, once the associated lambda bugs are fixed.
+

+
+
+
+

+ Conclusion +

+
+
+
+

+ We hope this post helps engineers elsewhere to develop better async task frameworks of their own. Many thanks to everyone who worked on this project: Anirudh Jayakumar, Deepak Gupta, Dmitry Kopytkov, Koundinya Muppalla, Peng Kang, Rajiv Desai, Ryan Armstrong, Steve Rodrigues, Thomissa Comellas, Xiaonan Zhang and Yuhuan Du.
+   +

+
+
+
+
+
+
+ // Tags
+ +
+
+ // Copy link
+ +
+ +
+
+
+
+
+
+
+
+ + + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected-metadata.json new file mode 100644 index 000000000..f2764b362 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Bradley M. Kuhn (http:\/\/ebb.org\/bkuhn\/)", + "Direction": null, + "Excerpt": "The website of Bradley M. Kuhn, aka Brad, aka bkuhn. This site includes his GPG keys, resume, blog, projects list, software, interviews, speeches and writing.", + "Image": null, + "Title": "On Recent Controversial Events - Bradley M. Kuhn ( Brad ) ( bkuhn )", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected.html new file mode 100644 index 000000000..a13415e45 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/expected.html @@ -0,0 +1,56 @@ +
+ +

+ Tuesday 15 October 2019 by Bradley M. Kuhn +

+

+ The last 33 days have been unprecedentedly difficult for the software freedom community and for me personally. Folks have been emailing, phoning, texting, tagging me on social media (— the last of which has been funny, because all my social media accounts are placeholder accounts). But, just about everyone has urged me to comment on the serious issues that the software freedom community now faces. Until now, I have stayed silent regarding all these current topics: from Richard M. Stallman (RMS)'s public statements, to his resignation from the Free Software Foundation (FSF), to the Epstein scandal and its connection to MIT. I've also avoided generally commenting on software freedom organizational governance during this period. I did this for good reason, which is explained below. However, in this blog post, I now share my primary comments on the matters that seem to currently be of the utmost attention of the Open Source and Free Software communities. +

+

+ I have been silent the last month because, until two days ago, I was an at-large member of FSF's Board of Directors, and a Voting Member of the FSF. As a member of FSF's two leadership bodies, I was abiding by a reasonable request from the FSF management and my duty to the organization. Specifically, the FSF asked that all communication during the crisis come directly from FSF officers and not from at-large directors and/or Voting Members. Furthermore, the FSF management asked all Directors and Voting Members to remain silent on this entire matter — even on issues only tangentially related to the current situation, and even when speaking in our own capacity (e.g., on our own blogs like this one). The FSF is an important organization, and I take any request from the FSF seriously — so I abided fully with their request. +

+

+ The situation was further complicated because folks at my employer, Software Freedom Conservancy (where I also serve on the Board of Directors) had strong opinions about this matter as well. Fortunately, the FSF and Conservancy both had already created clear protocols for what I should do if ever there was a disagreement or divergence of views between Conservancy and FSF. I therefore was recused fully from the planning, drafting, and timing of Conservancy's statement on this matter. I thank my colleagues at the Conservancy for working so carefully to keep me entirely outside the loop on their statement and to diligently assure that it was straight-forward for me to manage any potential organizational disagreements. I also thank those at the FSF who outlined clear protocols (ahead of time, back in March 2019) in case a situation like this ever came up. I also know my colleagues at Conservancy care deeply, as I do, about the health and welfare of the FSF and its mission of fighting for universal software freedom for all. None of us want, nor have, any substantive disagreement over software freedom issues. +

+

+ I take very seriously my duty to the various organizations where I have (or have had) affiliations. More generally, I champion non-profit organizational transparency. Unfortunately, the current crisis left me in a quandary between the overarching goal of community transparency and abiding by FSF management's directives. Now that I've left the FSF Board of Directors, FSF's Voting Membership, and all my FSF volunteer roles (which ends my 22-year uninterrupted affiliation with the FSF), I can now comment on the substantive issues that face not just the FSF, but the Free Software community as a whole, while continuing to adhere to my past duty of acting in FSF's best interest. In other words, my affiliation with the FSF has come to an end for many good and useful reasons. The end to this affiliation allows me to speak directly about the core issues at the heart of the community's current crisis. +

+

+ Firstly, all these events — from RMS' public comments on the MIT mailing list, to RMS' resignation from the FSF to RMS' discussions about the next steps for the GNU project — seem to many to have happened ridiculously quickly. But it wasn't actually fast at all. In fact, these events were culmination of issues that were slowly growing in concern to many people, including me. +

+

+ For the last two years, I had been a loud internal voice in the FSF leadership regarding RMS' Free-Software-unrelated public statements; I felt strongly that it was in the best interest of the FSF to actively seek to limit such statements, and that it was my duty to FSF to speak out about this within the organization. Those who only learned of this story in the last month (understandably) believed Selam G.'s Medium post raised an entirely new issue. In fact, RMS' views and statements posted on stallman.org about sexual morality escalated for the worse over the last few years. When the escalation started, I still considered RMS both a friend and colleague, and I attempted to argue with him at length to convince him that some of his positions were harmful to sexual assault survivors and those who are sex trafficked, and to the people who devote their lives in service to such individuals. More importantly to the FSF, I attempted to persuade RMS that launching a controversial campaign on sexual behavior and morality was counter to his and FSF's mission to advance software freedom, and told RMS that my duty as an FSF Director was to assure the best outcome for the FSF, which IMO didn't include having a leader who made such statements. Not only is human sexual behavior not a topic on which RMS has adequate academic expertise, but also his positions appear to ignore significant research and widely available information on the subject. Many of his comments, while occasionally politically intriguing, lack empathy for people who experienced trauma. +

+

+ IMO, this is not and has never been a Free Speech issue. I do believe freedom of speech links directly to software freedom: indeed, I see the freedom to publish software under Free licenses as almost a corollary to the freedom of speech. However, we do not need to follow leadership from those whose views we fundamentally disagree. Moreover, organizations need not and should not elevate spokespeople and leaders who speak regularly on unrelated issues that organizations find do not advance their mission, and/or that alienate important constituents. I, like many other software freedom leaders, curtail my public comments on issues not related to FOSS. (Indeed, I would not even be commenting on this issue if it had not become a central issue of concern to the software freedom community.) Leaders have power, and they must exercise the power of their words with restraint, not with impunity. +

+

+ RMS has consistently argued that there was a campaign of “prudish intimidation” — seeking to keep him quiet about his views on sexuality. After years of conversing with RMS about how his non-software-freedom views were a distraction, an indulgence, and downright problematic, his general response was to make even more public comments of this nature. The issue is not about RMS' right to say what he believes, nor is it even about whether or not you agree or disagree with RMS' statements. The question is whether an organization should have a designated leader who is on a sustained, public campaign advocating about an unrelated issue that many consider controversial. It really doesn't matter what your view about the controversial issue is; a leader who refuses to stop talking loudly about unrelated issues eventually creates an untenable distraction from the radical activism you're actively trying to advance. The message of universal software freedom is a radical cause; it's basically impossible for one individual to effectively push forward two unrelated controversial agendas at once. In short, the radical message of software freedom became overshadowed by RMS' radical views about sexual morality. +

+

+ And here is where I say the thing that may infuriate many but it's what I believe: I think RMS took a useful step by resigning some of his leadership roles at the FSF. I thank RMS for taking that step, and I wish the FSF Directors well in their efforts to assure that the FSF becomes a welcoming organization to all who care about universal software freedom. The FSF's mission is essential to our technological future, and we should all support that mission. I care deeply about that mission myself and have worked and will continue to work in our community in the best interest of the mission. +

+

+ I'm admittedly struggling to find a way to work again with RMS, given his views on sexual morality and his behaviors stemming from those views. I explicitly do not agree with this “(re-)definition” of sexual assault. Furthermore, I believe uninformed statements about sexual assault are irresponsible and cause harm to victims. #MeToo is not a “frenzy”; it is a global movement by individuals who have been harmed seeking to hold both bad actors and society-at-large accountable for ignoring systemic wrongs. Nevertheless, I still am proud of the essay that I co-wrote with RMS and still find many of RMS' other essays compelling, important, and relevant. +

+

+ I want the FSF to succeed in its mission and enter a new era of accomplishments. I've spent the last 22 years, without a break, dedicating substantial time, effort, care and loyalty to the various FSF roles that I've had: including employee, volunteer, at-large Director, and Voting Member. Even though my duties to the FSF are done, and my relationship with the FSF is no longer formal, I still think the FSF is a valuable institution worth helping and saving, specifically because the FSF was founded for a mission that I deeply support. And we should also realize that RMS — a human being (who is flawed like the rest of us) — invented that mission. +

+

+ As culture change becomes more rapid, I hope we can find reasonable nuance and moderation on our complex analysis about people and their disparate views, while we also hold individuals fully accountable for their actions. That's the difficulty we face in the post-post-modern culture of the early twenty-first century. Most importantly, I believe we must find a way to stand firm for software freedom while also making a safe environment for victims of sexual assault, sexual abuse, gaslighting, and other deplorable actions. +

+

+ Posted on Tuesday 15 October 2019 at 09:11 by Bradley M. Kuhn. +

+ + +

+ #include <std/disclaimer.h>
+ use Standard::Disclaimer;
+ from standard import disclaimer
+ SELECT full_text FROM standard WHERE type = 'disclaimer'; +

+ Both previously and presently, I have been employed by and/or done work for various organizations that also have views on Free, Libre, and Open Source Software. As should be blatantly obvious, this is my website, not theirs, so please do not assume views and opinions here belong to any such organization. Since I do co-own ebb.org with my wife, it may not be so obvious that these aren't her views and opinions, either. +

+ ebb is a service mark of Bradley M. Kuhn. +

\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/source.html new file mode 100644 index 000000000..5daa2a094 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/ebb-org/source.html @@ -0,0 +1,485 @@ + + + + + + On Recent Controversial Events - Bradley M. Kuhn ( Brad ) ( bkuhn ) + + + + + + + + + + + +
+ +
+
+

+ On Recent Controversial Events +

+

+ Tuesday 15 October 2019 by Bradley M. Kuhn +

+

+ The last 33 days have been unprecedentedly difficult for the software freedom community and for me personally. Folks have been emailing, phoning, texting, tagging me on social media (— the last of which has been funny, because all my social media accounts are placeholder accounts). But, just about everyone has urged me to comment on the serious issues that the software freedom community now faces. Until now, I have stayed silent regarding all these current topics: from Richard M. Stallman (RMS)'s public statements, to his resignation from the Free Software Foundation (FSF), to the Epstein scandal and its connection to MIT. I've also avoided generally commenting on software freedom organizational governance during this period. I did this for good reason, which is explained below. However, in this blog post, I now share my primary comments on the matters that seem to currently be of the utmost attention of the Open Source and Free Software communities. +

+

+ I have been silent the last month because, until two days ago, I was an at-large member of FSF's Board of Directors, and a Voting Member of the FSF. As a member of FSF's two leadership bodies, I was abiding by a reasonable request from the FSF management and my duty to the organization. Specifically, the FSF asked that all communication during the crisis come directly from FSF officers and not from at-large directors and/or Voting Members. Furthermore, the FSF management asked all Directors and Voting Members to remain silent on this entire matter — even on issues only tangentially related to the current situation, and even when speaking in our own capacity (e.g., on our own blogs like this one). The FSF is an important organization, and I take any request from the FSF seriously — so I abided fully with their request. +

+

+ The situation was further complicated because folks at my employer, Software Freedom Conservancy (where I also serve on the Board of Directors) had strong opinions about this matter as well. Fortunately, the FSF and Conservancy both had already created clear protocols for what I should do if ever there was a disagreement or divergence of views between Conservancy and FSF. I therefore was recused fully from the planning, drafting, and timing of Conservancy's statement on this matter. I thank my colleagues at the Conservancy for working so carefully to keep me entirely outside the loop on their statement and to diligently assure that it was straight-forward for me to manage any potential organizational disagreements. I also thank those at the FSF who outlined clear protocols (ahead of time, back in March 2019) in case a situation like this ever came up. I also know my colleagues at Conservancy care deeply, as I do, about the health and welfare of the FSF and its mission of fighting for universal software freedom for all. None of us want, nor have, any substantive disagreement over software freedom issues. +

+

+ I take very seriously my duty to the various organizations where I have (or have had) affiliations. More generally, I champion non-profit organizational transparency. Unfortunately, the current crisis left me in a quandary between the overarching goal of community transparency and abiding by FSF management's directives. Now that I've left the FSF Board of Directors, FSF's Voting Membership, and all my FSF volunteer roles (which ends my 22-year uninterrupted affiliation with the FSF), I can now comment on the substantive issues that face not just the FSF, but the Free Software community as a whole, while continuing to adhere to my past duty of acting in FSF's best interest. In other words, my affiliation with the FSF has come to an end for many good and useful reasons. The end to this affiliation allows me to speak directly about the core issues at the heart of the community's current crisis. +

+

+ Firstly, all these events — from RMS' public comments on the MIT mailing list, to RMS' resignation from the FSF to RMS' discussions about the next steps for the GNU project — seem to many to have happened ridiculously quickly. But it wasn't actually fast at all. In fact, these events were culmination of issues that were slowly growing in concern to many people, including me. +

+

+ For the last two years, I had been a loud internal voice in the FSF leadership regarding RMS' Free-Software-unrelated public statements; I felt strongly that it was in the best interest of the FSF to actively seek to limit such statements, and that it was my duty to FSF to speak out about this within the organization. Those who only learned of this story in the last month (understandably) believed Selam G.'s Medium post raised an entirely new issue. In fact, RMS' views and statements posted on stallman.org about sexual morality escalated for the worse over the last few years. When the escalation started, I still considered RMS both a friend and colleague, and I attempted to argue with him at length to convince him that some of his positions were harmful to sexual assault survivors and those who are sex trafficked, and to the people who devote their lives in service to such individuals. More importantly to the FSF, I attempted to persuade RMS that launching a controversial campaign on sexual behavior and morality was counter to his and FSF's mission to advance software freedom, and told RMS that my duty as an FSF Director was to assure the best outcome for the FSF, which IMO didn't include having a leader who made such statements. Not only is human sexual behavior not a topic on which RMS has adequate academic expertise, but also his positions appear to ignore significant research and widely available information on the subject. Many of his comments, while occasionally politically intriguing, lack empathy for people who experienced trauma. +

+

+ IMO, this is not and has never been a Free Speech issue. I do believe freedom of speech links directly to software freedom: indeed, I see the freedom to publish software under Free licenses as almost a corollary to the freedom of speech. However, we do not need to follow leadership from those whose views we fundamentally disagree. Moreover, organizations need not and should not elevate spokespeople and leaders who speak regularly on unrelated issues that organizations find do not advance their mission, and/or that alienate important constituents. I, like many other software freedom leaders, curtail my public comments on issues not related to FOSS. (Indeed, I would not even be commenting on this issue if it had not become a central issue of concern to the software freedom community.) Leaders have power, and they must exercise the power of their words with restraint, not with impunity. +

+

+ RMS has consistently argued that there was a campaign of “prudish intimidation” — seeking to keep him quiet about his views on sexuality. After years of conversing with RMS about how his non-software-freedom views were a distraction, an indulgence, and downright problematic, his general response was to make even more public comments of this nature. The issue is not about RMS' right to say what he believes, nor is it even about whether or not you agree or disagree with RMS' statements. The question is whether an organization should have a designated leader who is on a sustained, public campaign advocating about an unrelated issue that many consider controversial. It really doesn't matter what your view about the controversial issue is; a leader who refuses to stop talking loudly about unrelated issues eventually creates an untenable distraction from the radical activism you're actively trying to advance. The message of universal software freedom is a radical cause; it's basically impossible for one individual to effectively push forward two unrelated controversial agendas at once. In short, the radical message of software freedom became overshadowed by RMS' radical views about sexual morality. +

+

+ And here is where I say the thing that may infuriate many but it's what I believe: I think RMS took a useful step by resigning some of his leadership roles at the FSF. I thank RMS for taking that step, and I wish the FSF Directors well in their efforts to assure that the FSF becomes a welcoming organization to all who care about universal software freedom. The FSF's mission is essential to our technological future, and we should all support that mission. I care deeply about that mission myself and have worked and will continue to work in our community in the best interest of the mission. +

+

+ I'm admittedly struggling to find a way to work again with RMS, given his views on sexual morality and his behaviors stemming from those views. I explicitly do not agree with this “(re-)definition” of sexual assault. Furthermore, I believe uninformed statements about sexual assault are irresponsible and cause harm to victims. #MeToo is not a “frenzy”; it is a global movement by individuals who have been harmed seeking to hold both bad actors and society-at-large accountable for ignoring systemic wrongs. Nevertheless, I still am proud of the essay that I co-wrote with RMS and still find many of RMS' other essays compelling, important, and relevant. +

+

+ I want the FSF to succeed in its mission and enter a new era of accomplishments. I've spent the last 22 years, without a break, dedicating substantial time, effort, care and loyalty to the various FSF roles that I've had: including employee, volunteer, at-large Director, and Voting Member. Even though my duties to the FSF are done, and my relationship with the FSF is no longer formal, I still think the FSF is a valuable institution worth helping and saving, specifically because the FSF was founded for a mission that I deeply support. And we should also realize that RMS — a human being (who is flawed like the rest of us) — invented that mission. +

+

+ As culture change becomes more rapid, I hope we can find reasonable nuance and moderation on our complex analysis about people and their disparate views, while we also hold individuals fully accountable for their actions. That's the difficulty we face in the post-post-modern culture of the early twenty-first century. Most importantly, I believe we must find a way to stand firm for software freedom while also making a safe environment for victims of sexual assault, sexual abuse, gaslighting, and other deplorable actions. +

+

+ Posted on Tuesday 15 October 2019 at 09:11 by Bradley M. Kuhn. +

+

+ Submit comments on this post to <bkuhn@ebb.org>. +

+ +
+
+ +
+
+

+ Creative Commons License This website and all documents on it are licensed under a Creative Commons Attribution-Share Alike 3.0 United States License . +

+
+

+ #include <std/disclaimer.h>
+ use Standard::Disclaimer;
+ from standard import disclaimer
+ SELECT full_text FROM standard WHERE type = 'disclaimer'; +

+

+ Both previously and presently, I have been employed by and/or done work for various organizations that also have views on Free, Libre, and Open Source Software. As should be blatantly obvious, this is my website, not theirs, so please do not assume views and opinions here belong to any such organization. Since I do co-own ebb.org with my wife, it may not be so obvious that these aren't her views and opinions, either. +

+

+ — bkuhn +

+
+

+ ebb is a service mark of Bradley M. Kuhn. +

+
+ Bradley M. Kuhn <bkuhn@ebb.org> +
+
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected-images.json new file mode 100644 index 000000000..a44968377 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected-images.json @@ -0,0 +1,3 @@ +[ + "https:\/\/f.i.uol.com.br\/fotografia\/2018\/12\/21\/15454034955c1cfc67131dc_1545403495_3x2_rt.jpg" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected-metadata.json new file mode 100644 index 000000000..4d126413d --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Bruno (Henrique Zecchin) Rodrigues", + "Direction": null, + "Excerpt": "Na ocasi\u00e3o, t\u00e9cnico do Corinthians entregou r\u00e9plica do trof\u00e9u ao ex-presidente", + "Image": "https:\/\/f.i.uol.com.br\/fotografia\/2018\/12\/21\/15454034955c1cfc67131dc_1545403495_3x2_rt.jpg", + "Title": "Tite diz que errou ao levar ta\u00e7a da Libertadores a Lula em 2012", + "SiteName": "Folha de S.Paulo" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected.html new file mode 100644 index 000000000..13f3ac3e3 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/expected.html @@ -0,0 +1,24 @@ +
+

+ Após rechaçar um encontro da seleção brasileira com o presidente eleito Jair Bolsonaro, o técnico Tite declarou que errou ao levar a taça da Copa Libertadores de 2012, conquistada pelo Corinthians, ao ex-presidente Luiz Inácio Lula da Silva. +

+

+ Ao lado de representantes do clube paulista, o atual comandante do Brasil ainda entregou uma réplica do troféu a Lula. +

+

+ "Em 2012 eu errei. Ele não era presidente, mas fui ao Instituto e mandei felicitações por um aniversário. Não me posicionei politicamente. Não tenho partido político, tenho sim a torcida para que o Brasil seja melhor em igualdade social. E que nossas prioridades sejam educação e punição. Que seja dada a possibilidade de estudo ao garoto de São Braz, que não tem chão batido para ir à escola, ou da periferia de Caixas ou do morro do Rio de Janeiro. Seja dada a ele a prioridade de estudo e não a outras situações", falou Tite ao programa "Grande Círculo", que ainda irá ao ar no SporTV. +

+

+ Na ocasião, Tite e outros representantes do Corinthians foram ao Instituto Lula para mostrar a taça original da Libertadores ao ex-presidente. +

+ +

+ O assunto foi levantado porque recentemente Tite foi questionado se aceitaria um encontro da seleção brasileira com Bolsonaro em uma conquista de título ou antes da Copa América de 2019, por exemplo. O treinador deixou claro que preferiria evitar esse tipo de formalidade. +

+

+ Apesar disso, Tite não questionou a ação de Palmeiras e CBF, que convidaram Bolsonaro para a festa do título do Campeonato Brasileiro. O presidente eleito até levantou a taça conquistada pelo clube alviverde. +

+

+ "Em 2012 eu fiz e errei. O protocolo e a situação gerada no jogo do Palmeiras são fatos de opinião pessoal. CBF e Palmeiras, enquanto instituições têm a opinião. Errei lá atrás, não faria com o presidente antes da Copa e nem agora porque entendo que misturar esporte e política não é legal. Fiz errado lá atrás? Sim. Faria de novo? Não", acrescentou o comandante. +

+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/source.html new file mode 100644 index 000000000..03f749c1f --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/folha/source.html @@ -0,0 +1,2518 @@ + + + + + + + + Tite diz que errou ao levar taça da Libertadores a Lula em 2012 - 21/12/2018 - Esporte - Folha + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + +
+
+ +
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+
+ + + +
+ +
+ + + +
+
+ +
+ + + +
+
+
+
+
+
+
+
+
+

+ Tite diz que errou ao levar taça da Libertadores a Lula em 2012 +

+

+ Na ocasião, técnico do Corinthians entregou réplica do troféu ao ex-presidente +

+
+
+
+
    +
  • + +
  • +
  • +
    + + +
    +
  • +
+
+
+
+
+
+ Luiz Inácio Lula da Silva (ao centro) recebe de Tite e outros representantes do Corinthians réplica da taça da Libertadores +
+ Luiz Inácio Lula da Silva (ao centro) recebe de Tite e outros representantes do Corinthians réplica da taça da Libertadores - Heinrich Aikawa/Instituto Lula +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+ São Paulo +
+
+

+ Após rechaçar um encontro da seleção brasileira com o presidente eleito Jair Bolsonaro, o técnico Tite declarou que errou ao levar a taça da Copa Libertadores de 2012, conquistada pelo Corinthians, ao ex-presidente Luiz Inácio Lula da Silva. +

+

+ Ao lado de representantes do clube paulista, o atual comandante do Brasil ainda entregou uma réplica do troféu a Lula. +

+

+ "Em 2012 eu errei. Ele não era presidente, mas fui ao Instituto e mandei felicitações por um aniversário. Não me posicionei politicamente. Não tenho partido político, tenho sim a torcida para que o Brasil seja melhor em igualdade social. E que nossas prioridades sejam educação e punição. Que seja dada a possibilidade de estudo ao garoto de São Braz, que não tem chão batido para ir à escola, ou da periferia de Caixas ou do morro do Rio de Janeiro. Seja dada a ele a prioridade de estudo e não a outras situações", falou Tite ao programa "Grande Círculo", que ainda irá ao ar no SporTV. +

+

+ Na ocasião, Tite e outros representantes do Corinthians foram ao Instituto Lula para mostrar a taça original da Libertadores ao ex-presidente. +

+
+ +
+

+ O assunto foi levantado porque recentemente Tite foi questionado se aceitaria um encontro da seleção brasileira com Bolsonaro em uma conquista de título ou antes da Copa América de 2019, por exemplo. O treinador deixou claro que preferiria evitar esse tipo de formalidade. +

+

+ Apesar disso, Tite não questionou a ação de Palmeiras e CBF, que convidaram Bolsonaro para a festa do título do Campeonato Brasileiro. O presidente eleito até levantou a taça conquistada pelo clube alviverde. +

+

+ "Em 2012 eu fiz e errei. O protocolo e a situação gerada no jogo do Palmeiras são fatos de opinião pessoal. CBF e Palmeiras, enquanto instituições têm a opinião. Errei lá atrás, não faria com o presidente antes da Copa e nem agora porque entendo que misturar esporte e política não é legal. Fiz errado lá atrás? Sim. Faria de novo? Não", acrescentou o comandante. +

+
+
+ UOL +
+
+ +
+
+ Tópicos relacionados + +
+ + +
+
+

+ Comentários +

+

+ Os comentários não representam a opinião do jornal; a responsabilidade é do autor da mensagem. +

+ +
+ +
+ + +
+
+
+
+ +
+
+
+
+ + + +
+
+
+ +
+
+
+
+ +
+
+
+ NEWSLETTER +
+ +
+
+
+ + + + + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected-metadata.json new file mode 100644 index 000000000..41b1ff77f --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Written by Rob Ewaschuk\n Edited by Betsy Beyer", + "Direction": null, + "Excerpt": "Google\u2019s SRE teams have some basic principles and best practices for building successful monitoring and alerting systems. This chapter offers guidelines for what issues should interrupt a human via a page, and how to deal with issues that aren\u2019t serious enough to trigger a page.", + "Image": null, + "Title": "Google - Site Reliability Engineering", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected.html new file mode 100644 index 000000000..1461f276f --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/expected.html @@ -0,0 +1,458 @@ +
+

+ Monitoring Distributed Systems +

+ +

+ Google’s SRE teams have some basic principles and best practices for building successful monitoring and alerting systems. This chapter offers guidelines for what issues should interrupt a human via a page, and how to deal with issues that aren’t serious enough to trigger a page. +

+
+

+ Definitions +

+

+ There’s no uniformly shared vocabulary for discussing all topics related to monitoring. Even within Google, usage of the following terms varies, but the most common interpretations are listed here. +

+
+ +
+

+ Collecting, processing, aggregating, and displaying real-time quantitative data about a system, such as query counts and types, error counts and types, processing times, and server lifetimes. +

+
+ +
+

+ Monitoring based on metrics exposed by the internals of the system, including logs, interfaces like the Java Virtual Machine Profiling Interface, or an HTTP handler that emits internal statistics. +

+
+ +
+

+ Testing externally visible behavior as a user would see it. +

+
+ +
+

+ An application (usually web-based) that provides a summary view of a service’s core metrics. A dashboard may have filters, selectors, and so on, but is prebuilt to expose the metrics most important to its users. The dashboard might also display team information such as ticket queue length, a list of high-priority bugs, the current on-call engineer for a given area of responsibility, or recent pushes. +

+
+ +
+

+ A notification intended to be read by a human and that is pushed to a system such as a bug or ticket queue, an email alias, or a pager. Respectively, these alerts are classified as tickets, email alerts,22 and pages. +

+
+ +
+

+ A defect in a software or human system that, if repaired, instills confidence that this event won’t happen again in the same way. A given incident might have multiple root causes: for example, perhaps it was caused by a combination of insufficient process automation, software that crashed on bogus input, and insufficient testing of the script used to generate the configuration. Each of these factors might stand alone as a root cause, and each should be repaired. +

+
+
+ Node and machine +
+
+

+ Used interchangeably to indicate a single instance of a running kernel in either a physical server, virtual machine, or container. There might be multiple services worth monitoring on a single machine. The services may either be: +

+
    +
  • Related to each other: for example, a caching server and a web server +
  • +
  • Unrelated services sharing hardware: for example, a code repository and a master for a configuration system like Puppet or Chef +
  • +
+
+ +
+

+ Any change to a service’s running software or its configuration. +

+
+
+
+
+

+ Why Monitor? +

+

+ There are many reasons to monitor a system, including: +

+
+ +
+

+ How big is my database and how fast is it growing? How quickly is my daily-active user count growing? +

+
+ +
+

+ Are queries faster with Acme Bucket of Bytes 2.72 versus Ajax DB 3.14? How much better is my memcache hit rate with an extra node? Is my site slower than it was last week? +

+
+ +
+

+ Something is broken, and somebody needs to fix it right now! Or, something might break soon, so somebody should look soon. +

+
+ +
+

+ Dashboards should answer basic questions about your service, and normally include some form of the four golden signals (discussed in The Four Golden Signals). +

+
+ +
+

+ Our latency just shot up; what else happened around the same time? +

+
+
+

+ System monitoring is also helpful in supplying raw input into business analytics and in facilitating analysis of security breaches. Because this book focuses on the engineering domains in which SRE has particular expertise, we won’t discuss these applications of monitoring here. +

+

+ Monitoring and alerting enables a system to tell us when it’s broken, or perhaps to tell us what’s about to break. When the system isn’t able to automatically fix itself, we want a human to investigate the alert, determine if there’s a real problem at hand, mitigate the problem, and determine the root cause of the problem. Unless you’re performing security auditing on very narrowly scoped components of a system, you should never trigger an alert simply because "something seems a bit weird." +

+

+ Paging a human is a quite expensive use of an employee’s time. If an employee is at work, a page interrupts their workflow. If the employee is at home, a page interrupts their personal time, and perhaps even their sleep. When pages occur too frequently, employees second-guess, skim, or even ignore incoming alerts, sometimes even ignoring a "real" page that’s masked by the noise. Outages can be prolonged because other noise interferes with a rapid diagnosis and fix. Effective alerting systems have good signal and very low noise. +

+
+
+

+ Setting Reasonable Expectations for Monitoring +

+

+ Monitoring a complex application is a significant engineering endeavor in and of itself. Even with substantial existing infrastructure for instrumentation, collection, display, and alerting in place, a Google SRE team with 10–12 members typically has one or sometimes two members whose primary assignment is to build and maintain monitoring systems for their service. This number has decreased over time as we generalize and centralize common monitoring infrastructure, but every SRE team typically has at least one “monitoring person.” (That being said, while it can be fun to have access to traffic graph dashboards and the like, SRE teams carefully avoid any situation that requires someone to “stare at a screen to watch for problems.”) +

+

+ In general, Google has trended toward simpler and faster monitoring systems, with better tools for post hoc analysis. We avoid "magic" systems that try to learn thresholds or automatically detect causality. Rules that detect unexpected changes in end-user request rates are one counterexample; while these rules are still kept as simple as possible, they give a very quick detection of a very simple, specific, severe anomaly. Other uses of monitoring data such as capacity planning and traffic prediction can tolerate more fragility, and thus, more complexity. Observational experiments conducted over a very long time horizon (months or years) with a low sampling rate (hours or days) can also often tolerate more fragility because occasional missed samples won’t hide a long-running trend. +

+

+ Google SRE has experienced only limited success with complex dependency hierarchies. We seldom use rules such as, "If I know the database is slow, alert for a slow database; otherwise, alert for the website being generally slow." Dependency-reliant rules usually pertain to very stable parts of our system, such as our system for draining user traffic away from a datacenter. For example, "If a datacenter is drained, then don’t alert me on its latency" is one common datacenter alerting rule. Few teams at Google maintain complex dependency hierarchies because our infrastructure has a steady rate of continuous refactoring. +

+

+ Some of the ideas described in this chapter are still aspirational: there is always room to move more rapidly from symptom to root cause(s), especially in ever-changing systems. So while this chapter sets out some goals for monitoring systems, and some ways to achieve these goals, it’s important that monitoring systems—especially the critical path from the onset of a production problem, through a page to a human, through basic triage and deep debugging—be kept simple and comprehensible by everyone on the team. +

+

+ Similarly, to keep noise low and signal high, the elements of your monitoring system that direct to a pager need to be very simple and robust. Rules that generate alerts for humans should be simple to understand and represent a clear failure. +

+
+
+

+ Symptoms Versus Causes +

+

+ Your monitoring system should address two questions: what’s broken, and why? +

+

+ The "what’s broken" indicates the symptom; the "why" indicates a (possibly intermediate) cause. Table 6-1 lists some hypothetical symptoms and corresponding causes. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Table 6-1. Example symptoms and causes +
+ Symptom + + Cause +
+

+ I’m serving HTTP 500s or 404s +

+
+

+ Database servers are refusing connections +

+
+

+ My responses are slow +

+
+

+ CPUs are overloaded by a bogosort, or an Ethernet cable is crimped under a rack, visible as partial packet loss +

+
+

+ Users in Antarctica aren’t receiving animated cat GIFs +

+
+

+ Your Content Distribution Network hates scientists and felines, and thus blacklisted some client IPs +

+
+

+ Private content is world-readable +

+
+

+ A new software push caused ACLs to be forgotten and allowed all requests +

+
+

+ "What" versus "why" is one of the most important distinctions in writing good monitoring with maximum signal and minimum noise. +

+
+
+

+ Black-Box Versus White-Box +

+

+ We combine heavy use of white-box monitoring with modest but critical uses of black-box monitoring. The simplest way to think about black-box monitoring versus white-box monitoring is that black-box monitoring is symptom-oriented and represents active—not predicted—problems: "The system isn’t working correctly, right now." White-box monitoring depends on the ability to inspect the innards of the system, such as logs or HTTP endpoints, with instrumentation. White-box monitoring therefore allows detection of imminent problems, failures masked by retries, and so forth. +

+

+ Note that in a multilayered system, one person’s symptom is another person’s cause. For example, suppose that a database’s performance is slow. Slow database reads are a symptom for the database SRE who detects them. However, for the frontend SRE observing a slow website, the same slow database reads are a cause. Therefore, white-box monitoring is sometimes symptom-oriented, and sometimes cause-oriented, depending on just how informative your white-box is. +

+

+ When collecting telemetry for debugging, white-box monitoring is essential. If web servers seem slow on database-heavy requests, you need to know both how fast the web server perceives the database to be, and how fast the database believes itself to be. Otherwise, you can’t distinguish an actually slow database server from a network problem between your web server and your database. +

+

+ For paging, black-box monitoring has the key benefit of forcing discipline to only nag a human when a problem is both already ongoing and contributing to real symptoms. On the other hand, for not-yet-occurring but imminent problems, black-box monitoring is fairly useless. +

+
+
+

+ The Four Golden Signals +

+

+ The four golden signals of monitoring are latency, traffic, errors, and saturation. If you can only measure four metrics of your user-facing system, focus on these four. +

+
+ +
+

+ The time it takes to service a request. It’s important to distinguish between the latency of successful requests and the latency of failed requests. For example, an HTTP 500 error triggered due to loss of connection to a database or other critical backend might be served very quickly; however, as an HTTP 500 error indicates a failed request, factoring 500s into your overall latency might result in misleading calculations. On the other hand, a slow error is even worse than a fast error! Therefore, it’s important to track error latency, as opposed to just filtering out errors. +

+
+ +
+

+ A measure of how much demand is being placed on your system, measured in a high-level system-specific metric. For a web service, this measurement is usually HTTP requests per second, perhaps broken out by the nature of the requests (e.g., static versus dynamic content). For an audio streaming system, this measurement might focus on network I/O rate or concurrent sessions. For a key-value storage system, this measurement might be transactions and retrievals per second. +

+
+ +
+

+ The rate of requests that fail, either explicitly (e.g., HTTP 500s), implicitly (for example, an HTTP 200 success response, but coupled with the wrong content), or by policy (for example, "If you committed to one-second response times, any request over one second is an error"). Where protocol response codes are insufficient to express all failure conditions, secondary (internal) protocols may be necessary to track partial failure modes. Monitoring these cases can be drastically different: catching HTTP 500s at your load balancer can do a decent job of catching all completely failed requests, while only end-to-end system tests can detect that you’re serving the wrong content. +

+
+ +
+

+ How "full" your service is. A measure of your system fraction, emphasizing the resources that are most constrained (e.g., in a memory-constrained system, show memory; in an I/O-constrained system, show I/O). Note that many systems degrade in performance before they achieve 100% utilization, so having a utilization target is essential. +

+

+ In complex systems, saturation can be supplemented with higher-level load measurement: can your service properly handle double the traffic, handle only 10% more traffic, or handle even less traffic than it currently receives? For very simple services that have no parameters that alter the complexity of the request (e.g., "Give me a nonce" or "I need a globally unique monotonic integer") that rarely change configuration, a static value from a load test might be adequate. As discussed in the previous paragraph, however, most services need to use indirect signals like CPU utilization or network bandwidth that have a known upper bound. Latency increases are often a leading indicator of saturation. Measuring your 99th percentile response time over some small window (e.g., one minute) can give a very early signal of saturation. +

+

+ Finally, saturation is also concerned with predictions of impending saturation, such as "It looks like your database will fill its hard drive in 4 hours." +

+
+
+

+ If you measure all four golden signals and page a human when one signal is problematic (or, in the case of saturation, nearly problematic), your service will be at least decently covered by monitoring. +

+
+
+

+ Worrying About Your Tail (or, Instrumentation and Performance) +

+

+ When building a monitoring system from scratch, it’s tempting to design a system based upon the mean of some quantity: the mean latency, the mean CPU usage of your nodes, or the mean fullness of your databases. The danger presented by the latter two cases is obvious: CPUs and databases can easily be utilized in a very imbalanced way. The same holds for latency. If you run a web service with an average latency of 100 ms at 1,000 requests per second, 1% of requests might easily take 5 seconds.23 If your users depend on several such web services to render their page, the 99th percentile of one backend can easily become the median response of your frontend. +

+

+ The simplest way to differentiate between a slow average and a very slow "tail" of requests is to collect request counts bucketed by latencies (suitable for rendering a histogram), rather than actual latencies: how many requests did I serve that took between 0 ms and 10 ms, between 10 ms and 30 ms, between 30 ms and 100 ms, between 100 ms and 300 ms, and so on? Distributing the histogram boundaries approximately exponentially (in this case by factors of roughly 3) is often an easy way to visualize the distribution of your requests. +

+
+
+

+ Choosing an Appropriate Resolution for Measurements +

+

+ Different aspects of a system should be measured with different levels of granularity. For example: +

+
    +
  • Observing CPU load over the time span of a minute won’t reveal even quite long-lived spikes that drive high tail latencies. +
  • +
  • On the other hand, for a web service targeting no more than 9 hours aggregate downtime per year (99.9% annual uptime), probing for a 200 (success) status more than once or twice a minute is probably unnecessarily frequent. +
  • +
  • Similarly, checking hard drive fullness for a service targeting 99.9% availability more than once every 1–2 minutes is probably unnecessary. +
  • +
+

+ Take care in how you structure the granularity of your measurements. Collecting per-second measurements of CPU load might yield interesting data, but such frequent measurements may be very expensive to collect, store, and analyze. If your monitoring goal calls for high resolution but doesn’t require extremely low latency, you can reduce these costs by performing internal sampling on the server, then configuring an external system to collect and aggregate that distribution over time or across servers. You might: +

+
    +
  1. Record the current CPU utilization each second. +
  2. +
  3. Using buckets of 5% granularity, increment the appropriate CPU utilization bucket each second. +
  4. +
  5. Aggregate those values every minute. +
  6. +
+

+ This strategy allows you to observe brief CPU hotspots without incurring very high cost due to collection and retention. +

+
+
+

+ As Simple as Possible, No Simpler +

+

+ Piling all these requirements on top of each other can add up to a very complex monitoring system—your system might end up with the following levels of complexity: +

+
    +
  • Alerts on different latency thresholds, at different percentiles, on all kinds of different metrics +
  • +
  • Extra code to detect and expose possible causes +
  • +
  • Associated dashboards for each of these possible causes +
  • +
+

+ The sources of potential complexity are never-ending. Like all software systems, monitoring can become so complex that it’s fragile, complicated to change, and a maintenance burden. +

+

+ Therefore, design your monitoring system with an eye toward simplicity. In choosing what to monitor, keep the following guidelines in mind: +

+
    +
  • The rules that catch real incidents most often should be as simple, predictable, and reliable as possible. +
  • +
  • Data collection, aggregation, and alerting configuration that is rarely exercised (e.g., less than once a quarter for some SRE teams) should be up for removal. +
  • +
  • Signals that are collected, but not exposed in any prebaked dashboard nor used by any alert, are candidates for removal. +
  • +
+

+ In Google’s experience, basic collection and aggregation of metrics, paired with alerting and dashboards, has worked well as a relatively standalone system. (In fact Google’s monitoring system is broken up into several binaries, but typically people learn about all aspects of these binaries.) It can be tempting to combine monitoring with other aspects of inspecting complex systems, such as detailed system profiling, single-process debugging, tracking details about exceptions or crashes, load testing, log collection and analysis, or traffic inspection. While most of these subjects share commonalities with basic monitoring, blending together too many results in overly complex and fragile systems. As in many other aspects of software engineering, maintaining distinct systems with clear, simple, loosely coupled points of integration is a better strategy (for example, using web APIs for pulling summary data in a format that can remain constant over an extended period of time). +

+
+
+

+ Tying These Principles Together +

+

+ The principles discussed in this chapter can be tied together into a philosophy on monitoring and alerting that’s widely endorsed and followed within Google SRE teams. While this monitoring philosophy is a bit aspirational, it’s a good starting point for writing or reviewing a new alert, and it can help your organization ask the right questions, regardless of the size of your organization or the complexity of your service or system. +

+

+ When creating rules for monitoring and alerting, asking the following questions can help you avoid false positives and pager burnout:24 +

+
    +
  • Does this rule detect an otherwise undetected condition that is urgent, actionable, and actively or imminently user-visible?25 +
  • +
  • Will I ever be able to ignore this alert, knowing it’s benign? When and why will I be able to ignore this alert, and how can I avoid this scenario? +
  • +
  • Does this alert definitely indicate that users are being negatively affected? Are there detectable cases in which users aren’t being negatively impacted, such as drained traffic or test deployments, that should be filtered out? +
  • +
  • Can I take action in response to this alert? Is that action urgent, or could it wait until morning? Could the action be safely automated? Will that action be a long-term fix, or just a short-term workaround? +
  • +
  • Are other people getting paged for this issue, therefore rendering at least one of the pages unnecessary? +
  • +
+

+ These questions reflect a fundamental philosophy on pages and pagers: +

+
    +
  • Every time the pager goes off, I should be able to react with a sense of urgency. I can only react with a sense of urgency a few times a day before I become fatigued. +
  • +
  • Every page should be actionable. +
  • +
  • Every page response should require intelligence. If a page merely merits a robotic response, it shouldn’t be a page. +
  • +
  • Pages should be about a novel problem or an event that hasn’t been seen before. +
  • +
+

+ Such a perspective dissipates certain distinctions: if a page satisfies the preceding four bullets, it’s irrelevant whether the page is triggered by white-box or black-box monitoring. This perspective also amplifies certain distinctions: it’s better to spend much more effort on catching symptoms than causes; when it comes to causes, only worry about very definite, very imminent causes. +

+
+
+

+ Monitoring for the Long Term +

+

+ In modern production systems, monitoring systems track an ever-evolving system with changing software architecture, load characteristics, and performance targets. An alert that’s currently exceptionally rare and hard to automate might become frequent, perhaps even meriting a hacked-together script to resolve it. At this point, someone should find and eliminate the root causes of the problem; if such resolution isn’t possible, the alert response deserves to be fully automated. +

+

+ It’s important that decisions about monitoring be made with long-term goals in mind. Every page that happens today distracts a human from improving the system for tomorrow, so there is often a case for taking a short-term hit to availability or performance in order to improve the long-term outlook for the system. Let’s take a look at two case studies that illustrate this trade-off. +

+
+ +

+ Google’s internal infrastructure is typically offered and measured against a service level objective (SLO; see Service Level Objectives). Many years ago, the Bigtable service’s SLO was based on a synthetic well-behaved client’s mean performance. Because of problems in Bigtable and lower layers of the storage stack, the mean performance was driven by a "large" tail: the worst 5% of requests were often significantly slower than the rest. +

+

+ Email alerts were triggered as the SLO approached, and paging alerts were triggered when the SLO was exceeded. Both types of alerts were firing voluminously, consuming unacceptable amounts of engineering time: the team spent significant amounts of time triaging the alerts to find the few that were really actionable, and we often missed the problems that actually affected users, because so few of them did. Many of the pages were non-urgent, due to well-understood problems in the infrastructure, and had either rote responses or received no response. +

+

+ To remedy the situation, the team used a three-pronged approach: while making great efforts to improve the performance of Bigtable, we also temporarily dialed back our SLO target, using the 75th percentile request latency. We also disabled email alerts, as there were so many that spending time diagnosing them was infeasible. +

+

+ This strategy gave us enough breathing room to actually fix the longer-term problems in Bigtable and the lower layers of the storage stack, rather than constantly fixing tactical problems. On-call engineers could actually accomplish work when they weren’t being kept up by pages at all hours. Ultimately, temporarily backing off on our alerts allowed us to make faster progress toward a better service. +

+
+
+ +

+ In the very early days of Gmail, the service was built on a retrofitted distributed process management system called Workqueue, which was originally created for batch processing of pieces of the search index. Workqueue was "adapted" to long-lived processes and subsequently applied to Gmail, but certain bugs in the relatively opaque codebase in the scheduler proved hard to beat. +

+

+ At that time, the Gmail monitoring was structured such that alerts fired when individual tasks were “de-scheduled” by Workqueue. This setup was less than ideal because even at that time, Gmail had many, many thousands of tasks, each task representing a fraction of a percent of our users. We cared deeply about providing a good user experience for Gmail users, but such an alerting setup was unmaintainable. +

+

+ To address this problem, Gmail SRE built a tool that helped “poke” the scheduler in just the right way to minimize impact to users. The team had several discussions about whether or not we should simply automate the entire loop from detecting the problem to nudging the rescheduler, until a better long-term solution was achieved, but some worried this kind of workaround would delay a real fix. +

+

+ This kind of tension is common within a team, and often reflects an underlying mistrust of the team’s self-discipline: while some team members want to implement a “hack” to allow time for a proper fix, others worry that a hack will be forgotten or that the proper fix will be deprioritized indefinitely. This concern is credible, as it’s easy to build layers of unmaintainable technical debt by patching over problems instead of making real fixes. Managers and technical leaders play a key role in implementing true, long-term fixes by supporting and prioritizing potentially time-consuming long-term fixes even when the initial “pain” of paging subsides. +

+

+ Pages with rote, algorithmic responses should be a red flag. Unwillingness on the part of your team to automate such pages implies that the team lacks confidence that they can clean up their technical debt. This is a major problem worth escalating. +

+
+
+ +

+ A common theme connects the previous examples of Bigtable and Gmail: a tension between short-term and long-term availability. Often, sheer force of effort can help a rickety system achieve high availability, but this path is usually short-lived and fraught with burnout and dependence on a small number of heroic team members. Taking a controlled, short-term decrease in availability is often a painful, but strategic trade for the long-run stability of the system. It’s important not to think of every page as an event in isolation, but to consider whether the overall level of paging leads toward a healthy, appropriately available system with a healthy, viable team and long-term outlook. We review statistics about page frequency (usually expressed as incidents per shift, where an incident might be composed of a few related pages) in quarterly reports with management, ensuring that decision makers are kept up to date on the pager load and overall health of their teams. +

+
+
+
+

+ Conclusion +

+

+ A healthy monitoring and alerting pipeline is simple and easy to reason about. It focuses primarily on symptoms for paging, reserving cause-oriented heuristics to serve as aids to debugging problems. Monitoring symptoms is easier the further "up" your stack you monitor, though monitoring saturation and performance of subsystems such as databases often must be performed directly on the subsystem itself. Email alerts are of very limited value and tend to easily become overrun with noise; instead, you should favor a dashboard that monitors all ongoing subcritical problems for the sort of information that typically ends up in email alerts. A dashboard might also be paired with a log, in order to analyze historical correlations. +

+

+ Over the long haul, achieving a successful on-call rotation and product includes choosing to alert on symptoms or imminent real problems, adapting your targets to goals that are actually achievable, and making sure that your monitoring supports rapid diagnosis. +

+
+ +
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/source.html new file mode 100644 index 000000000..6fb202427 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/google-sre-book-1/source.html @@ -0,0 +1,742 @@ + + + + + + + Google - Site Reliability Engineering + + + + + + + + + + + + +
+
+ +
+ +

+ Chapter 6 - Monitoring Distributed Systems +

+
+
+ + +
+
+
+
+
+
+

+ Monitoring Distributed Systems +

+ +

+ Google’s SRE teams have some basic principles and best practices for building successful monitoring and alerting systems. This chapter offers guidelines for what issues should interrupt a human via a page, and how to deal with issues that aren’t serious enough to trigger a page. +

+
+

+ Definitions +

+

+ There’s no uniformly shared vocabulary for discussing all topics related to monitoring. Even within Google, usage of the following terms varies, but the most common interpretations are listed here. +

+
+
+ Monitoring +
+
+

+ Collecting, processing, aggregating, and displaying real-time quantitative data about a system, such as query counts and types, error counts and types, processing times, and server lifetimes. +

+
+
+ White-box monitoring +
+
+

+ Monitoring based on metrics exposed by the internals of the system, including logs, interfaces like the Java Virtual Machine Profiling Interface, or an HTTP handler that emits internal statistics. +

+
+
+ Black-box monitoring +
+
+

+ Testing externally visible behavior as a user would see it. +

+
+
+ Dashboard +
+
+

+ An application (usually web-based) that provides a summary view of a service’s core metrics. A dashboard may have filters, selectors, and so on, but is prebuilt to expose the metrics most important to its users. The dashboard might also display team information such as ticket queue length, a list of high-priority bugs, the current on-call engineer for a given area of responsibility, or recent pushes. +

+
+
+ Alert +
+
+

+ A notification intended to be read by a human and that is pushed to a system such as a bug or ticket queue, an email alias, or a pager. Respectively, these alerts are classified as tickets, email alerts,22 and pages. +

+
+
+ Root cause +
+
+

+ A defect in a software or human system that, if repaired, instills confidence that this event won’t happen again in the same way. A given incident might have multiple root causes: for example, perhaps it was caused by a combination of insufficient process automation, software that crashed on bogus input, and insufficient testing of the script used to generate the configuration. Each of these factors might stand alone as a root cause, and each should be repaired. +

+
+
+ Node and machine +
+
+

+ Used interchangeably to indicate a single instance of a running kernel in either a physical server, virtual machine, or container. There might be multiple services worth monitoring on a single machine. The services may either be: +

+
    +
  • Related to each other: for example, a caching server and a web server +
  • +
  • Unrelated services sharing hardware: for example, a code repository and a master for a configuration system like Puppet or Chef +
  • +
+
+
+ Push +
+
+

+ Any change to a service’s running software or its configuration. +

+
+
+
+
+

+ Why Monitor? +

+

+ There are many reasons to monitor a system, including: +

+
+ +
+

+ How big is my database and how fast is it growing? How quickly is my daily-active user count growing? +

+
+
+ Comparing over time or experiment groups +
+
+

+ Are queries faster with Acme Bucket of Bytes 2.72 versus Ajax DB 3.14? How much better is my memcache hit rate with an extra node? Is my site slower than it was last week? +

+
+
+ Alerting +
+
+

+ Something is broken, and somebody needs to fix it right now! Or, something might break soon, so somebody should look soon. +

+
+
+ Building dashboards +
+
+

+ Dashboards should answer basic questions about your service, and normally include some form of the four golden signals (discussed in The Four Golden Signals). +

+
+
+ Conducting ad hoc retrospective analysis (i.e., debugging) +
+
+

+ Our latency just shot up; what else happened around the same time? +

+
+
+

+ System monitoring is also helpful in supplying raw input into business analytics and in facilitating analysis of security breaches. Because this book focuses on the engineering domains in which SRE has particular expertise, we won’t discuss these applications of monitoring here. +

+

+ Monitoring and alerting enables a system to tell us when it’s broken, or perhaps to tell us what’s about to break. When the system isn’t able to automatically fix itself, we want a human to investigate the alert, determine if there’s a real problem at hand, mitigate the problem, and determine the root cause of the problem. Unless you’re performing security auditing on very narrowly scoped components of a system, you should never trigger an alert simply because "something seems a bit weird." +

+

+ Paging a human is a quite expensive use of an employee’s time. If an employee is at work, a page interrupts their workflow. If the employee is at home, a page interrupts their personal time, and perhaps even their sleep. When pages occur too frequently, employees second-guess, skim, or even ignore incoming alerts, sometimes even ignoring a "real" page that’s masked by the noise. Outages can be prolonged because other noise interferes with a rapid diagnosis and fix. Effective alerting systems have good signal and very low noise. +

+
+
+

+ Setting Reasonable Expectations for Monitoring +

+

+ Monitoring a complex application is a significant engineering endeavor in and of itself. Even with substantial existing infrastructure for instrumentation, collection, display, and alerting in place, a Google SRE team with 10–12 members typically has one or sometimes two members whose primary assignment is to build and maintain monitoring systems for their service. This number has decreased over time as we generalize and centralize common monitoring infrastructure, but every SRE team typically has at least one “monitoring person.” (That being said, while it can be fun to have access to traffic graph dashboards and the like, SRE teams carefully avoid any situation that requires someone to “stare at a screen to watch for problems.”) +

+

+ In general, Google has trended toward simpler and faster monitoring systems, with better tools for post hoc analysis. We avoid "magic" systems that try to learn thresholds or automatically detect causality. Rules that detect unexpected changes in end-user request rates are one counterexample; while these rules are still kept as simple as possible, they give a very quick detection of a very simple, specific, severe anomaly. Other uses of monitoring data such as capacity planning and traffic prediction can tolerate more fragility, and thus, more complexity. Observational experiments conducted over a very long time horizon (months or years) with a low sampling rate (hours or days) can also often tolerate more fragility because occasional missed samples won’t hide a long-running trend. +

+

+ Google SRE has experienced only limited success with complex dependency hierarchies. We seldom use rules such as, "If I know the database is slow, alert for a slow database; otherwise, alert for the website being generally slow." Dependency-reliant rules usually pertain to very stable parts of our system, such as our system for draining user traffic away from a datacenter. For example, "If a datacenter is drained, then don’t alert me on its latency" is one common datacenter alerting rule. Few teams at Google maintain complex dependency hierarchies because our infrastructure has a steady rate of continuous refactoring. +

+

+ Some of the ideas described in this chapter are still aspirational: there is always room to move more rapidly from symptom to root cause(s), especially in ever-changing systems. So while this chapter sets out some goals for monitoring systems, and some ways to achieve these goals, it’s important that monitoring systems—especially the critical path from the onset of a production problem, through a page to a human, through basic triage and deep debugging—be kept simple and comprehensible by everyone on the team. +

+

+ Similarly, to keep noise low and signal high, the elements of your monitoring system that direct to a pager need to be very simple and robust. Rules that generate alerts for humans should be simple to understand and represent a clear failure. +

+
+
+

+ Symptoms Versus Causes +

+

+ Your monitoring system should address two questions: what’s broken, and why? +

+

+ The "what’s broken" indicates the symptom; the "why" indicates a (possibly intermediate) cause. Table 6-1 lists some hypothetical symptoms and corresponding causes. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Table 6-1. Example symptoms and causes +
+ Symptom + + Cause +
+

+ I’m serving HTTP 500s or 404s +

+
+

+ Database servers are refusing connections +

+
+

+ My responses are slow +

+
+

+ CPUs are overloaded by a bogosort, or an Ethernet cable is crimped under a rack, visible as partial packet loss +

+
+

+ Users in Antarctica aren’t receiving animated cat GIFs +

+
+

+ Your Content Distribution Network hates scientists and felines, and thus blacklisted some client IPs +

+
+

+ Private content is world-readable +

+
+

+ A new software push caused ACLs to be forgotten and allowed all requests +

+
+

+ "What" versus "why" is one of the most important distinctions in writing good monitoring with maximum signal and minimum noise. +

+
+
+

+ Black-Box Versus White-Box +

+

+ We combine heavy use of white-box monitoring with modest but critical uses of black-box monitoring. The simplest way to think about black-box monitoring versus white-box monitoring is that black-box monitoring is symptom-oriented and represents active—not predicted—problems: "The system isn’t working correctly, right now." White-box monitoring depends on the ability to inspect the innards of the system, such as logs or HTTP endpoints, with instrumentation. White-box monitoring therefore allows detection of imminent problems, failures masked by retries, and so forth. +

+

+ Note that in a multilayered system, one person’s symptom is another person’s cause. For example, suppose that a database’s performance is slow. Slow database reads are a symptom for the database SRE who detects them. However, for the frontend SRE observing a slow website, the same slow database reads are a cause. Therefore, white-box monitoring is sometimes symptom-oriented, and sometimes cause-oriented, depending on just how informative your white-box is. +

+

+ When collecting telemetry for debugging, white-box monitoring is essential. If web servers seem slow on database-heavy requests, you need to know both how fast the web server perceives the database to be, and how fast the database believes itself to be. Otherwise, you can’t distinguish an actually slow database server from a network problem between your web server and your database. +

+

+ For paging, black-box monitoring has the key benefit of forcing discipline to only nag a human when a problem is both already ongoing and contributing to real symptoms. On the other hand, for not-yet-occurring but imminent problems, black-box monitoring is fairly useless. +

+
+
+

+ The Four Golden Signals +

+

+ The four golden signals of monitoring are latency, traffic, errors, and saturation. If you can only measure four metrics of your user-facing system, focus on these four. +

+
+
+ Latency +
+
+

+ The time it takes to service a request. It’s important to distinguish between the latency of successful requests and the latency of failed requests. For example, an HTTP 500 error triggered due to loss of connection to a database or other critical backend might be served very quickly; however, as an HTTP 500 error indicates a failed request, factoring 500s into your overall latency might result in misleading calculations. On the other hand, a slow error is even worse than a fast error! Therefore, it’s important to track error latency, as opposed to just filtering out errors. +

+
+
+ Traffic +
+
+

+ A measure of how much demand is being placed on your system, measured in a high-level system-specific metric. For a web service, this measurement is usually HTTP requests per second, perhaps broken out by the nature of the requests (e.g., static versus dynamic content). For an audio streaming system, this measurement might focus on network I/O rate or concurrent sessions. For a key-value storage system, this measurement might be transactions and retrievals per second. +

+
+
+ Errors +
+
+

+ The rate of requests that fail, either explicitly (e.g., HTTP 500s), implicitly (for example, an HTTP 200 success response, but coupled with the wrong content), or by policy (for example, "If you committed to one-second response times, any request over one second is an error"). Where protocol response codes are insufficient to express all failure conditions, secondary (internal) protocols may be necessary to track partial failure modes. Monitoring these cases can be drastically different: catching HTTP 500s at your load balancer can do a decent job of catching all completely failed requests, while only end-to-end system tests can detect that you’re serving the wrong content. +

+
+
+ Saturation +
+
+

+ How "full" your service is. A measure of your system fraction, emphasizing the resources that are most constrained (e.g., in a memory-constrained system, show memory; in an I/O-constrained system, show I/O). Note that many systems degrade in performance before they achieve 100% utilization, so having a utilization target is essential. +

+

+ In complex systems, saturation can be supplemented with higher-level load measurement: can your service properly handle double the traffic, handle only 10% more traffic, or handle even less traffic than it currently receives? For very simple services that have no parameters that alter the complexity of the request (e.g., "Give me a nonce" or "I need a globally unique monotonic integer") that rarely change configuration, a static value from a load test might be adequate. As discussed in the previous paragraph, however, most services need to use indirect signals like CPU utilization or network bandwidth that have a known upper bound. Latency increases are often a leading indicator of saturation. Measuring your 99th percentile response time over some small window (e.g., one minute) can give a very early signal of saturation. +

+

+ Finally, saturation is also concerned with predictions of impending saturation, such as "It looks like your database will fill its hard drive in 4 hours." +

+
+
+

+ If you measure all four golden signals and page a human when one signal is problematic (or, in the case of saturation, nearly problematic), your service will be at least decently covered by monitoring. +

+
+
+

+ Worrying About Your Tail (or, Instrumentation and Performance) +

+

+ When building a monitoring system from scratch, it’s tempting to design a system based upon the mean of some quantity: the mean latency, the mean CPU usage of your nodes, or the mean fullness of your databases. The danger presented by the latter two cases is obvious: CPUs and databases can easily be utilized in a very imbalanced way. The same holds for latency. If you run a web service with an average latency of 100 ms at 1,000 requests per second, 1% of requests might easily take 5 seconds.23 If your users depend on several such web services to render their page, the 99th percentile of one backend can easily become the median response of your frontend. +

+

+ The simplest way to differentiate between a slow average and a very slow "tail" of requests is to collect request counts bucketed by latencies (suitable for rendering a histogram), rather than actual latencies: how many requests did I serve that took between 0 ms and 10 ms, between 10 ms and 30 ms, between 30 ms and 100 ms, between 100 ms and 300 ms, and so on? Distributing the histogram boundaries approximately exponentially (in this case by factors of roughly 3) is often an easy way to visualize the distribution of your requests. +

+
+
+

+ Choosing an Appropriate Resolution for Measurements +

+

+ Different aspects of a system should be measured with different levels of granularity. For example: +

+
    +
  • Observing CPU load over the time span of a minute won’t reveal even quite long-lived spikes that drive high tail latencies. +
  • +
  • On the other hand, for a web service targeting no more than 9 hours aggregate downtime per year (99.9% annual uptime), probing for a 200 (success) status more than once or twice a minute is probably unnecessarily frequent. +
  • +
  • Similarly, checking hard drive fullness for a service targeting 99.9% availability more than once every 1–2 minutes is probably unnecessary. +
  • +
+

+ Take care in how you structure the granularity of your measurements. Collecting per-second measurements of CPU load might yield interesting data, but such frequent measurements may be very expensive to collect, store, and analyze. If your monitoring goal calls for high resolution but doesn’t require extremely low latency, you can reduce these costs by performing internal sampling on the server, then configuring an external system to collect and aggregate that distribution over time or across servers. You might: +

+
    +
  1. Record the current CPU utilization each second. +
  2. +
  3. Using buckets of 5% granularity, increment the appropriate CPU utilization bucket each second. +
  4. +
  5. Aggregate those values every minute. +
  6. +
+

+ This strategy allows you to observe brief CPU hotspots without incurring very high cost due to collection and retention. +

+
+
+

+ As Simple as Possible, No Simpler +

+

+ Piling all these requirements on top of each other can add up to a very complex monitoring system—your system might end up with the following levels of complexity: +

+
    +
  • Alerts on different latency thresholds, at different percentiles, on all kinds of different metrics +
  • +
  • Extra code to detect and expose possible causes +
  • +
  • Associated dashboards for each of these possible causes +
  • +
+

+ The sources of potential complexity are never-ending. Like all software systems, monitoring can become so complex that it’s fragile, complicated to change, and a maintenance burden. +

+

+ Therefore, design your monitoring system with an eye toward simplicity. In choosing what to monitor, keep the following guidelines in mind: +

+
    +
  • The rules that catch real incidents most often should be as simple, predictable, and reliable as possible. +
  • +
  • Data collection, aggregation, and alerting configuration that is rarely exercised (e.g., less than once a quarter for some SRE teams) should be up for removal. +
  • +
  • Signals that are collected, but not exposed in any prebaked dashboard nor used by any alert, are candidates for removal. +
  • +
+

+ In Google’s experience, basic collection and aggregation of metrics, paired with alerting and dashboards, has worked well as a relatively standalone system. (In fact Google’s monitoring system is broken up into several binaries, but typically people learn about all aspects of these binaries.) It can be tempting to combine monitoring with other aspects of inspecting complex systems, such as detailed system profiling, single-process debugging, tracking details about exceptions or crashes, load testing, log collection and analysis, or traffic inspection. While most of these subjects share commonalities with basic monitoring, blending together too many results in overly complex and fragile systems. As in many other aspects of software engineering, maintaining distinct systems with clear, simple, loosely coupled points of integration is a better strategy (for example, using web APIs for pulling summary data in a format that can remain constant over an extended period of time). +

+
+
+

+ Tying These Principles Together +

+

+ The principles discussed in this chapter can be tied together into a philosophy on monitoring and alerting that’s widely endorsed and followed within Google SRE teams. While this monitoring philosophy is a bit aspirational, it’s a good starting point for writing or reviewing a new alert, and it can help your organization ask the right questions, regardless of the size of your organization or the complexity of your service or system. +

+

+ When creating rules for monitoring and alerting, asking the following questions can help you avoid false positives and pager burnout:24 +

+
    +
  • Does this rule detect an otherwise undetected condition that is urgent, actionable, and actively or imminently user-visible?25 +
  • +
  • Will I ever be able to ignore this alert, knowing it’s benign? When and why will I be able to ignore this alert, and how can I avoid this scenario? +
  • +
  • Does this alert definitely indicate that users are being negatively affected? Are there detectable cases in which users aren’t being negatively impacted, such as drained traffic or test deployments, that should be filtered out? +
  • +
  • Can I take action in response to this alert? Is that action urgent, or could it wait until morning? Could the action be safely automated? Will that action be a long-term fix, or just a short-term workaround? +
  • +
  • Are other people getting paged for this issue, therefore rendering at least one of the pages unnecessary? +
  • +
+

+ These questions reflect a fundamental philosophy on pages and pagers: +

+
    +
  • Every time the pager goes off, I should be able to react with a sense of urgency. I can only react with a sense of urgency a few times a day before I become fatigued. +
  • +
  • Every page should be actionable. +
  • +
  • Every page response should require intelligence. If a page merely merits a robotic response, it shouldn’t be a page. +
  • +
  • Pages should be about a novel problem or an event that hasn’t been seen before. +
  • +
+

+ Such a perspective dissipates certain distinctions: if a page satisfies the preceding four bullets, it’s irrelevant whether the page is triggered by white-box or black-box monitoring. This perspective also amplifies certain distinctions: it’s better to spend much more effort on catching symptoms than causes; when it comes to causes, only worry about very definite, very imminent causes. +

+
+
+

+ Monitoring for the Long Term +

+

+ In modern production systems, monitoring systems track an ever-evolving system with changing software architecture, load characteristics, and performance targets. An alert that’s currently exceptionally rare and hard to automate might become frequent, perhaps even meriting a hacked-together script to resolve it. At this point, someone should find and eliminate the root causes of the problem; if such resolution isn’t possible, the alert response deserves to be fully automated. +

+

+ It’s important that decisions about monitoring be made with long-term goals in mind. Every page that happens today distracts a human from improving the system for tomorrow, so there is often a case for taking a short-term hit to availability or performance in order to improve the long-term outlook for the system. Let’s take a look at two case studies that illustrate this trade-off. +

+
+

+ Bigtable SRE: A Tale of Over-Alerting +

+

+ Google’s internal infrastructure is typically offered and measured against a service level objective (SLO; see Service Level Objectives). Many years ago, the Bigtable service’s SLO was based on a synthetic well-behaved client’s mean performance. Because of problems in Bigtable and lower layers of the storage stack, the mean performance was driven by a "large" tail: the worst 5% of requests were often significantly slower than the rest. +

+

+ Email alerts were triggered as the SLO approached, and paging alerts were triggered when the SLO was exceeded. Both types of alerts were firing voluminously, consuming unacceptable amounts of engineering time: the team spent significant amounts of time triaging the alerts to find the few that were really actionable, and we often missed the problems that actually affected users, because so few of them did. Many of the pages were non-urgent, due to well-understood problems in the infrastructure, and had either rote responses or received no response. +

+

+ To remedy the situation, the team used a three-pronged approach: while making great efforts to improve the performance of Bigtable, we also temporarily dialed back our SLO target, using the 75th percentile request latency. We also disabled email alerts, as there were so many that spending time diagnosing them was infeasible. +

+

+ This strategy gave us enough breathing room to actually fix the longer-term problems in Bigtable and the lower layers of the storage stack, rather than constantly fixing tactical problems. On-call engineers could actually accomplish work when they weren’t being kept up by pages at all hours. Ultimately, temporarily backing off on our alerts allowed us to make faster progress toward a better service. +

+
+
+

+ Gmail: Predictable, Scriptable Responses from Humans +

+

+ In the very early days of Gmail, the service was built on a retrofitted distributed process management system called Workqueue, which was originally created for batch processing of pieces of the search index. Workqueue was "adapted" to long-lived processes and subsequently applied to Gmail, but certain bugs in the relatively opaque codebase in the scheduler proved hard to beat. +

+

+ At that time, the Gmail monitoring was structured such that alerts fired when individual tasks were “de-scheduled” by Workqueue. This setup was less than ideal because even at that time, Gmail had many, many thousands of tasks, each task representing a fraction of a percent of our users. We cared deeply about providing a good user experience for Gmail users, but such an alerting setup was unmaintainable. +

+

+ To address this problem, Gmail SRE built a tool that helped “poke” the scheduler in just the right way to minimize impact to users. The team had several discussions about whether or not we should simply automate the entire loop from detecting the problem to nudging the rescheduler, until a better long-term solution was achieved, but some worried this kind of workaround would delay a real fix. +

+

+ This kind of tension is common within a team, and often reflects an underlying mistrust of the team’s self-discipline: while some team members want to implement a “hack” to allow time for a proper fix, others worry that a hack will be forgotten or that the proper fix will be deprioritized indefinitely. This concern is credible, as it’s easy to build layers of unmaintainable technical debt by patching over problems instead of making real fixes. Managers and technical leaders play a key role in implementing true, long-term fixes by supporting and prioritizing potentially time-consuming long-term fixes even when the initial “pain” of paging subsides. +

+

+ Pages with rote, algorithmic responses should be a red flag. Unwillingness on the part of your team to automate such pages implies that the team lacks confidence that they can clean up their technical debt. This is a major problem worth escalating. +

+
+
+

+ The Long Run +

+

+ A common theme connects the previous examples of Bigtable and Gmail: a tension between short-term and long-term availability. Often, sheer force of effort can help a rickety system achieve high availability, but this path is usually short-lived and fraught with burnout and dependence on a small number of heroic team members. Taking a controlled, short-term decrease in availability is often a painful, but strategic trade for the long-run stability of the system. It’s important not to think of every page as an event in isolation, but to consider whether the overall level of paging leads toward a healthy, appropriately available system with a healthy, viable team and long-term outlook. We review statistics about page frequency (usually expressed as incidents per shift, where an incident might be composed of a few related pages) in quarterly reports with management, ensuring that decision makers are kept up to date on the pager load and overall health of their teams. +

+
+
+
+

+ Conclusion +

+

+ A healthy monitoring and alerting pipeline is simple and easy to reason about. It focuses primarily on symptoms for paging, reserving cause-oriented heuristics to serve as aids to debugging problems. Monitoring symptoms is easier the further "up" your stack you monitor, though monitoring saturation and performance of subsystems such as databases often must be performed directly on the subsystem itself. Email alerts are of very limited value and tend to easily become overrun with noise; instead, you should favor a dashboard that monitors all ongoing subcritical problems for the sort of information that typically ends up in email alerts. A dashboard might also be paired with a log, in order to analyze historical correlations. +

+

+ Over the long haul, achieving a successful on-call rotation and product includes choosing to alert on symptoms or imminent real problems, adapting your targets to goals that are actually achievable, and making sure that your monitoring supports rapid diagnosis. +

+
+
+

+ 22Sometimes known as "alert spam," as they are rarely read or acted on. +

+

+ 23If 1% of your requests are 50x the average, it means that the rest of your requests are about twice as fast as the average. But if you’re not measuring your distribution, the idea that most of your requests are near the mean is just hopeful thinking. +

+

+ 24See Applying Cardiac Alarm Management Techniques to Your On-Call [Hol14] for an example of alert fatigue in another context. +

+

+ 25Zero-redundancy (N + 0) situations count as imminent, as do "nearly full" parts of your service! For more details about the concept of redundancy, see https://en.wikipedia.org/wiki/N%2B1_redundancy. +

+
+
+
+
+ +
+ + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected-images.json new file mode 100644 index 000000000..e99978bb5 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected-images.json @@ -0,0 +1,16 @@ +[ + "https:\/\/i.guim.co.uk\/img\/media\/df84b519a877d652e950ecd4248320eec985934e\/0_320_4800_2880\/master\/4800.jpg?width=1200&height=630&quality=85&auto=format&fit=crop&overlay-align=bottom%2Cleft&overlay-width=100p&overlay-base64=L2ltZy9zdGF0aWMvb3ZlcmxheXMvdGctZGVmYXVsdC5wbmc&s=af41545b21b557e4f57dd4221b6a7f89", + "https:\/\/i.guim.co.uk\/img\/media\/05cb692c634cd90e5411aab92ca3e649474ff786\/0_0_4800_3200\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=575838a657b26493e956c7f84b058080", + "https:\/\/i.guim.co.uk\/img\/media\/98c683a7df9c83b2c13de2d93ca1825199ed5150\/0_0_4800_3166\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=2f198e1958f140f3ac664a3fdd87177c", + "https:\/\/i.guim.co.uk\/img\/media\/0447972cf47ca67882fcfc648edf7e574b0853bc\/0_0_4800_3200\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=718132fd888108a18383c24a8425523b", + "https:\/\/i.guim.co.uk\/img\/media\/416800b8d06039780c3e6de28564e6f277b4e7b7\/0_0_4800_3200\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=c5a53178ebbe54490c97fad6b5e032c4", + "https:\/\/i.guim.co.uk\/img\/media\/8c207197c0a9e6f407dcddfded5f868a142c9cab\/0_0_4800_3200\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=0dd659ae339b1aea9a99ed7f6f8eadeb", + "https:\/\/i.guim.co.uk\/img\/media\/0d13adeb0790af5c5fa317ce477c323d0e1c773c\/0_0_4800_2334\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=41b88ee343b9be76688b88443c7a8958", + "https:\/\/i.guim.co.uk\/img\/media\/4973b41f53b8ade499f99a305b01157eca659ca5\/0_0_1200_900\/master\/1200.jpg?width=300&quality=85&auto=format&fit=max&s=7c255bf6f8a27c56365a86813cdd1517", + "https:\/\/i.guim.co.uk\/img\/media\/d1941b6a6908314fab28f44da222a4c892213341\/0_0_4800_3120\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=76a26a289728e3d625e57d32eced57d8", + "https:\/\/i.guim.co.uk\/img\/media\/14b462f5d9489def554e0f9f436f13aec332f7b8\/0_0_4278_4800\/master\/4278.jpg?width=300&quality=85&auto=format&fit=max&s=a45ec7578a392eec201d2f6920b609a0", + "https:\/\/i.guim.co.uk\/img\/media\/e2cf54c36f17c6894844ea0cdd4346288a002da9\/915_0_3172_3189\/master\/3172.jpg?width=300&quality=85&auto=format&fit=max&s=0bd8e9f51bdf79a6e0a15ed176cfb57d", + "https:\/\/i.guim.co.uk\/img\/media\/b5f3736b2ba2ef4df364258b0efcaba26f571d6e\/0_0_4800_3073\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=7fcadc35b3a44ebafe3c469c6e89241d", + "https:\/\/i.guim.co.uk\/img\/media\/d5aaf60e3a427f278747acf0c3e7ba39b39ef923\/0_0_4800_3200\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=1b74b488aedb864287ff160f86d74c9d", + "https:\/\/i.guim.co.uk\/img\/media\/3766106f73e858d5b140ae3cdd2eef84060180cd\/0_0_4800_3200\/master\/4800.jpg?width=300&quality=85&auto=format&fit=max&s=d2f5bb7c3c3642ac8733ca40509f6e20" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected-metadata.json new file mode 100644 index 000000000..47af67cd3 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Eleanor Ainge Roy", + "Direction": null, + "Excerpt": "New Zealand\u2019s whale whisperers worry that manmade changes in the ocean are behind the spike in beachings", + "Image": "https:\/\/i.guim.co.uk\/img\/media\/df84b519a877d652e950ecd4248320eec985934e\/0_320_4800_2880\/master\/4800.jpg?width=1200&height=630&quality=85&auto=format&fit=crop&overlay-align=bottom%2Cleft&overlay-width=100p&overlay-base64=L2ltZy9zdGF0aWMvb3ZlcmxheXMvdGctZGVmYXVsdC5wbmc&s=af41545b21b557e4f57dd4221b6a7f89", + "Title": "'What is the sea telling us?': M\u0101ori tribes fearful over whale strandings | Eleanor Ainge Roy", + "SiteName": "the Guardian" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected.html new file mode 100644 index 000000000..b7faebd36 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/expected.html @@ -0,0 +1,297 @@ +
+

+ Whale whisperer Hori Parata was just seven years old when he attended his first mass stranding, a beaching of porpoises in New Zealand’s Northland, their cries screeching through the air on the deserted stretch of sand. +

+

+ Seven decades later, Parata, 75, has now overseen more than 500 strandings and is renowned in New Zealand as the leading Māori whale expert, called on by tribes around the country for cultural guidance as marine strandings become increasingly complex and fatal. +

+

+ “Man’s greed in the ocean is hurting the whales,” says Parata, a fierce and uncompromising elder of the Ngātiwai tribe of eastern Northland. +

+
+ + + +
+ + + Hori Parata at his Pātaua farm, the place where he was born and grew up. +
+
+
+ +

+ “We’re having to put up with a lot of stuff today. The public want to hug the whales, they want to touch them, they want to feel good – that’s not the thing. We feel that is ridiculous.” +

+

+ Whale experts regard New Zealand – or Aotearoa as it is called by Māori – as the whale stranding capital of the world, with more than 5,000 incidents recorded since 1840, and an average of 300 individual animals beaching themselves each year. +

+
+ + + +
+ + + Kauri (Tekaurinui Robert) Parata, watched by his father Hori Parata, carves a traditional Maōri design at their home in Whangārei. Kauri is a member of the Manu Taupunga group that is the organising arm of the whale-body recovery operation started by his father, Hori Parata +
+
+
+ +

+ Concrete information on why whales strand remains elusive, but “sickness, navigational error, geographical features, a rapidly falling tide, being chased by a predator, or extreme weather” are all thought to contribute, according to the New Zealand Department of Conservation. +

+

+ Climate change is to blame too, scientists think, with warming ocean temperatures moving whales’ prey closer to the shore and forcing them to pursue their food into shallow waters. +

+
+ + + +
+ + + A bin of small whale bones. +
+
+
+
+ + + +
+ + + The baleen recovered from a stranded Pygmy Right Whale. +
+
+
+
+ + + +
+ + + Squid beaks, from the stomach of a Sperm Whale. +
+
+
+ +

+ ‘Unprecedented’ strandings +

+

+ November marked the beginning of whale stranding season, and it started with a surge in incidents, according to whale rescue group Project Jonah, with 140 pilot whales beaching and dying on Stewart Island, 10 rare pygmy whales on Ninety Mile beach, 51 stranded and dead on the Chatham Islands and a spate of individual cases around the country. +

+

+ And as more whales beach and die – from exhaustion, heat stroke or seagulls feasting on their flesh – an acute sense of grief is growing among New Zealand’s indigenous people, who regard whales as their ancestors and taonga (treasures). +

+

+ “These days it is like a zoo. People just want to come and gawk at us, without even trying to understand what is happening with the animals and the environment,” says Parata, bristling with anger. +

+
+ whale strandings +
+

+ “When will we talk about what is hurting these animals out on the sea? They are drowning out there, they can’t breathe, they beach themselves to be with the Aunties.” +

+

+ Ngātiwai believe the whales beach when they are ready to die and want to return to their families, the Māori people. Then, their human families use the whales’ gift of their bodies for sacred carvings, for traditional medicines, and even for compost. +

+

+ There are marked tribal differences across New Zealand and while some tribes work to refloat stranded whales, others like Parata’s Ngātiwai stand back and allow the Department of Conservation and volunteer groups to take the lead in rescue efforts. +

+

+ Then the tribe moves in en masse and holds a karakia (prayer), names each animal and sets to work removing their bones, blubber, eyes and teeth for cultural purposes. +

+
+ + + +
+ + + Buck Cullen with his daughter Kaiarahi (10 months) in his back yard where he is storing a pair of massive Sperm Whale jawbones. Buck is a integral member of the whale recovery team, alongside Hori Parata. +
+
+
+ +

+ But indigenous elders say they aren’t being listened to when they tell the government their whale kin are sick, and trying to escape an increasingly polluted and unpredictable ocean. +

+

+ Earlier this year in South Taranaki, a mass stranding that was described as “unprecedented” left the local Māori tribe scrambling. Security was brought in when thieves attacked a sperm whale with an axe, trying to remove valuable teeth from its jaw. +

+
+ + + +
+ + + 12 Parāoa Whales (Sperm Whales) recently stranded on the South Taranaki coast of Kaupokonui, on a scale not seen on their coast in recent memory. +
+
+
+ +

+ Parata and his 22-year-old son, Te Kaurinui Robert Parata, were called in to assist. Te Kaurinui was called after the first whale his father ever named, and left university this year to return to Whangārei and study whale tikanga (protocol) and carving. +

+

+ He says mass strandings are getting more local and international attention and money from donations, but traditional knowledge is being dismissed as overly spiritual. +

+
+ + + +
+ + + Kauri (Tekaurinui Robert) Parata, of the New Zealand Māori tribe Ngāti Wai, in front of the carving shed at Hihiaua Cultural Centre in Whangarei +
+
+
+ +

+ ‘We need to listen’ +

+

+ Māori harvest rights over dead whales have only been officially recognised since 1998, and the practice still elicits horror from some New Zealanders and visitors. +

+

+ “Our own ancestors wouldn’t say to go down there and hug the whales. That’s a modern thing,” says Te Kaurinui. +

+
+ + + +
+ + + The Pou in front of the carving shed at Hihiaua Cultural centre +
+
+
+
+ + + +
+ + + Kauri (Tekaurinui Robert) Parata, holds three whale teeth recovered from a beached whale. The middle tooth shows the marks where a poacher had attempted to hack it out with an axe before the recovery group arrived. Kauri is a member of the Manu Taupunga group that is the organising arm of the whale-body recovery operation started by his father, Hori Parata. +
+
+
+

+ The Ngātiwai are investigating a possible link between the crisis of the dieback disease killing New Zealand’s native kauri trees – and threatening the giant Tāne Mahuta, which may be 2,000 years old – and the increase in whale strandings. +

+

+ Parata and his family believe whale oil and byproducts could be used to try to cure Kauri dieback, and want more government money and attention directed towards indigenous knowledge of the interconnectedness of the New Zealand environment, and possible indigenous solutions. +

+

+ “People dismiss us when we tell them our spiritual understanding of whales – why they are beaching, why they are hurting,” says Te Kaurinui. +

+
+ + + +
+ + + Whangārei Harbour from Tamaterau, looking south through Mangrove sprouts coming up through the harbourside silt. +
+
+
+ +

+ “We are not foreigners in this land. We did not take this land off anyone else. We were not lost waiting for some bullheads to tell us what was going on.” +

+

+ Kaitaia conservation department ranger Jamie Werner of Ngātiwai recently attended his first mass beaching on Ninety Mile Beach. It was the first recorded time pygmy whales had stranded on New Zealand shores. +

+

+ “I arrived at the beach and we leapfrogged between the animals. They were calling out to each other and reassuring each other,” says Werner. “It was a shock. We’re working to adapt but the ocean is changing so fast.” +

+
+ + + +
+ + + The skull of a Brydes whale, in the storage container at Hihiaua Cultural Centre, Whangārei. +
+
+
+ +
+ + + +
+ + + A large calibre bullet of the type that the New Zealand Department of Conservation (DOC) uses for euthanasing stranded whales that are beyond rescue. +
+
+
+

+ The recent spate of mass strandings has been described as “heartbreaking” by the conservation department. +

+

+ But for Parata and his family the slow, painful deaths of their ancestors are personal – and ultimately devastating – for the health of the tribe and the sea. +

+

+ “It’s very emotional. Our ancestors tell us the strandings are a sign from the sea. So what is the sea telling us? We need to listen.” +

+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/source.html new file mode 100644 index 000000000..a61316266 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/guardian-1/source.html @@ -0,0 +1,1369 @@ + + + + + 'What is the sea telling us?': Māori tribes fearful over whale strandings | Eleanor Ainge Roy | Environment | The Guardian + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + +
+
+
+ +
+
+
+
+ +

+ New Zealand’s whale whisperers worry that manmade changes in the ocean are behind the spike in beachings +

+

+ by (reporting) and Adrian Malloch (photography) +

+
+
+ Main image: Whale expert Hori Parata. Photograph: Adrian Malloch for the Guardian +
+
+
+
+
+
+
+
+ +
+ + +
+
+

+ 'What is the sea telling us?': Māori tribes fearful over whale strandings +

+
+
+
+
+ +
+

+ Whale whisperer Hori Parata was just seven years old when he attended his first mass stranding, a beaching of porpoises in New Zealand’s Northland, their cries screeching through the air on the deserted stretch of sand. +

+

+ Seven decades later, Parata, 75, has now overseen more than 500 strandings and is renowned in New Zealand as the leading Māori whale expert, called on by tribes around the country for cultural guidance as marine strandings become increasingly complex and fatal. +

+

+ “Man’s greed in the ocean is hurting the whales,” says Parata, a fierce and uncompromising elder of the Ngātiwai tribe of eastern Northland. +

+
+ + + +
+ + + Hori Parata at his Pātaua farm, the place where he was born and grew up. +
+
+
+
    +
  • +

    + Hori Parata at his Pātaua farm, the place where he was born and grew up +

    +
  • +
+

+ “We’re having to put up with a lot of stuff today. The public want to hug the whales, they want to touch them, they want to feel good – that’s not the thing. We feel that is ridiculous.” +

+

+ Whale experts regard New Zealand – or Aotearoa as it is called by Māori – as the whale stranding capital of the world, with more than 5,000 incidents recorded since 1840, and an average of 300 individual animals beaching themselves each year. +

+
+ + + +
+ + + Kauri (Tekaurinui Robert) Parata, watched by his father Hori Parata, carves a traditional Maōri design at their home in Whangārei. Kauri is a member of the Manu Taupunga group that is the organising arm of the whale-body recovery operation started by his father, Hori Parata +
+
+
+
    +
  • +

    + Kauri (Te Kaurinui Robert) Parata, watched by his father, Hori Parata, carves a traditional Māori design at their home in Whangārei. Kauri is a member of the Manu Taupunga group that is the organising arm of the whale-body recovery operation started by his father +

    +
  • +
+

+ Concrete information on why whales strand remains elusive, but “sickness, navigational error, geographical features, a rapidly falling tide, being chased by a predator, or extreme weather” are all thought to contribute, according to the New Zealand Department of Conservation. +

+

+ Climate change is to blame too, scientists think, with warming ocean temperatures moving whales’ prey closer to the shore and forcing them to pursue their food into shallow waters. +

+
+ + + +
+ + + A bin of small whale bones. +
+
+
+
+ + + +
+ + + The baleen recovered from a stranded Pygmy Right Whale. +
+
+
+
+ + + +
+ + + Squid beaks, from the stomach of a Sperm Whale. +
+
+
+
    +
  • +

    + Clockwise from top: small whale bones; squid beaks, from the stomach of a sperm whale; the baleen filter-feeder system recovered from a stranded pygmy right whale. +

    +
  • +
+

+ ‘Unprecedented’ strandings +

+

+ November marked the beginning of whale stranding season, and it started with a surge in incidents, according to whale rescue group Project Jonah, with 140 pilot whales beaching and dying on Stewart Island, 10 rare pygmy whales on Ninety Mile beach, 51 stranded and dead on the Chatham Islands and a spate of individual cases around the country. +

+

+ And as more whales beach and die – from exhaustion, heat stroke or seagulls feasting on their flesh – an acute sense of grief is growing among New Zealand’s indigenous people, who regard whales as their ancestors and taonga (treasures). +

+

+ “These days it is like a zoo. People just want to come and gawk at us, without even trying to understand what is happening with the animals and the environment,” says Parata, bristling with anger. +

+
+ whale strandings +
+

+ “When will we talk about what is hurting these animals out on the sea? They are drowning out there, they can’t breathe, they beach themselves to be with the Aunties.” +

+

+ Ngātiwai believe the whales beach when they are ready to die and want to return to their families, the Māori people. Then, their human families use the whales’ gift of their bodies for sacred carvings, for traditional medicines, and even for compost. +

+

+ There are marked tribal differences across New Zealand and while some tribes work to refloat stranded whales, others like Parata’s Ngātiwai stand back and allow the Department of Conservation and volunteer groups to take the lead in rescue efforts. +

+

+ Then the tribe moves in en masse and holds a karakia (prayer), names each animal and sets to work removing their bones, blubber, eyes and teeth for cultural purposes. +

+
+ + + +
+ + + Buck Cullen with his daughter Kaiarahi (10 months) in his back yard where he is storing a pair of massive Sperm Whale jawbones. Buck is a integral member of the whale recovery team, alongside Hori Parata. +
+
+
+
    +
  • +

    + Buck Cullen with his daughter Kaiarahi (10 months) in his backyard, where he is storing a pair of massive sperm whale jawbones. Cullen is an integral member of Hori Parata’s whale recovery team +

    +
  • +
+

+ But indigenous elders say they aren’t being listened to when they tell the government their whale kin are sick, and trying to escape an increasingly polluted and unpredictable ocean. +

+

+ Earlier this year in South Taranaki, a mass stranding that was described as “unprecedented” left the local Māori tribe scrambling. Security was brought in when thieves attacked a sperm whale with an axe, trying to remove valuable teeth from its jaw. +

+
+ + + +
+ + + 12 Parāoa Whales (Sperm Whales) recently stranded on the South Taranaki coast of Kaupokonui, on a scale not seen on their coast in recent memory. +
+
+
+
    +
  • +

    + 12 parāoa whales (sperm whales) recently stranded on the South Taranaki coast of Kaupokonui, on a scale not seen near this location in recent memory +

    +
  • +
+

+ Parata and his 22-year-old son, Te Kaurinui Robert Parata, were called in to assist. Te Kaurinui was called after the first whale his father ever named, and left university this year to return to Whangārei and study whale tikanga (protocol) and carving. +

+

+ He says mass strandings are getting more local and international attention and money from donations, but traditional knowledge is being dismissed as overly spiritual. +

+
+ + + +
+ + + Kauri (Tekaurinui Robert) Parata, of the New Zealand Māori tribe Ngāti Wai, in front of the carving shed at Hihiaua Cultural Centre in Whangarei +
+
+
+
    +
  • +

    + Clockwise from top: Te Kaurinui Parata, in front of the carving shed at Hihiaua Cultural Centre in Whangārei; Parata holds three whale teeth recovered from a beached whale – the middle one shows marks where a poacher had attempted to hack it out with an axe before the recovery group arrived; the Pou, a tribal identifier, in front of the carving shed. +

    +
  • +
+

+ ‘We need to listen’ +

+

+ Māori harvest rights over dead whales have only been officially recognised since 1998, and the practice still elicits horror from some New Zealanders and visitors. +

+

+ “Our own ancestors wouldn’t say to go down there and hug the whales. That’s a modern thing,” says Te Kaurinui. +

+
+ + + +
+ + + The Pou in front of the carving shed at Hihiaua Cultural centre +
+
+
+
+ + + +
+ + + Kauri (Tekaurinui Robert) Parata, holds three whale teeth recovered from a beached whale. The middle tooth shows the marks where a poacher had attempted to hack it out with an axe before the recovery group arrived. Kauri is a member of the Manu Taupunga group that is the organising arm of the whale-body recovery operation started by his father, Hori Parata. +
+
+
+

+ The Ngātiwai are investigating a possible link between the crisis of the dieback disease killing New Zealand’s native kauri trees – and threatening the giant Tāne Mahuta, which may be 2,000 years old – and the increase in whale strandings. +

+

+ Parata and his family believe whale oil and byproducts could be used to try to cure Kauri dieback, and want more government money and attention directed towards indigenous knowledge of the interconnectedness of the New Zealand environment, and possible indigenous solutions. +

+

+ “People dismiss us when we tell them our spiritual understanding of whales – why they are beaching, why they are hurting,” says Te Kaurinui. +

+
+ + + +
+ + + Whangārei Harbour from Tamaterau, looking south through Mangrove sprouts coming up through the harbourside silt. +
+
+
+
    +
  • +

    + Whangārei Harbour seen from Tamaterau, with mangrove sprouts coming up through the harbourside silt +

    +
  • +
+

+ “We are not foreigners in this land. We did not take this land off anyone else. We were not lost waiting for some bullheads to tell us what was going on.” +

+

+ Kaitaia conservation department ranger Jamie Werner of Ngātiwai recently attended his first mass beaching on Ninety Mile Beach. It was the first recorded time pygmy whales had stranded on New Zealand shores. +

+

+ “I arrived at the beach and we leapfrogged between the animals. They were calling out to each other and reassuring each other,” says Werner. “It was a shock. We’re working to adapt but the ocean is changing so fast.” +

+
+ + + +
+ + + The skull of a Brydes whale, in the storage container at Hihiaua Cultural Centre, Whangārei. +
+
+
+
    +
  • +

    + Above, the skull of a bryde’s whale; right, a large-calibre bullet of the type that the New Zealand Department of Conservation uses for euthanasing stranded whales that are beyond rescue +

    +
  • +
+
+ + + +
+ + + A large calibre bullet of the type that the New Zealand Department of Conservation (DOC) uses for euthanasing stranded whales that are beyond rescue. +
+
+
+

+ The recent spate of mass strandings has been described as “heartbreaking” by the conservation department. +

+

+ But for Parata and his family the slow, painful deaths of their ancestors are personal – and ultimately devastating – for the health of the tribe and the sea. +

+

+ “It’s very emotional. Our ancestors tell us the strandings are a sign from the sea. So what is the sea telling us? We need to listen.” +

+
+ +
+
+ +
+
+
+ + + + + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected-metadata.json new file mode 100644 index 000000000..611a1553b --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": "abc", + "Image": null, + "Title": "Replace javascript: links", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected.html new file mode 100644 index 000000000..2e73a80ea --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/expected.html @@ -0,0 +1,7 @@ +
+ +

abc

+

def

+ ghi +
+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/source.html new file mode 100644 index 000000000..ee63fc89b --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/js-link-replacement/source.html @@ -0,0 +1,14 @@ + + + + + Replace javascript: links + + + +

abc

+

def

+ ghi +
+ + \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected-images.json new file mode 100644 index 000000000..a748bac39 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected-images.json @@ -0,0 +1,19 @@ +[ + "http:\/\/www.factorio.com\/static\/img\/factorio-wheel.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-277-finished-2.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-newly-finished.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-277-not-finished-2.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-blueprint-library-grid-view.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-blueprint-library-list-view.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-blueprint-book.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-the-hand.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-enemy-bases.gif", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-cliff-controls.gif", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-rectangles.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-moisture+aux-debug-map.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-moisture+aux-controls.gif", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-island.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-islands.png", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-accumulator.gif", + "https:\/\/cdn.factorio.com\/assets\/img\/blog\/fff-282-accumulator-comparison.png" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected-metadata.json new file mode 100644 index 000000000..820a3d07a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": "Posted by kovarex, TOGos, Ernestas, Albert on 2019-02-15, all posts", + "Image": "http:\/\/www.factorio.com\/static\/img\/factorio-wheel.png", + "Title": "Friday Facts #282 - 0.17 in sight | Factorio", + "SiteName": "Factorio.com" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected.html new file mode 100644 index 000000000..0f86741bf --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/expected.html @@ -0,0 +1,524 @@ +
+ +

Posted by kovarex, TOGos, Ernestas, Albert on 2019-02-15, all posts

+ +

The release plan (kovarex) +

+

This week was the time to close and finish all the things that will go to 0.17.0.

+

Not all of the things that we originally planned to be done were done (surprise), but we just left any non-essential stuff for later so we won't postpone the release any further. The plan is, that next week will be dedicated to the office playtesting and bugfixing. Many would argue, that we could just release instantly and let the players find the bugs for us, but we want to fix the most obvious problems in-house to avoid too many duplicate bug reports and chaos after the release. Also, some potential bugs, like save corruptions, are much more easily worked on in-house.

+

+ If the playtesting goes well, we will let you know next Friday, and if it is the case, we will aim to release the week starting 25th February. +

+

After release plan

+

+ Since there are a lot of things we would like to do before we can call 0.17 good enough, we will simply push new things into the 0.17 releases as time goes on. Even if 0.17 becomes stable in a reasonable time, we would still push things on top of it. We can still make experimental/stable version numbers inside 0.17. Most of the things shouldn't be big enough to make the game generally unstable. I've heard countless times a proposal to make small frequent releases of what have we added, this will probably be reality after 0.17 for some time. +

+

+ The smaller releases will contain mainly: +

+ + +

+ This is actually quite a large change to our procedures, and there are many ways we will be trying to maximize the effectiveness of smaller and more regular content updates. +

+

The GUI progress (kovarex) +

+

+ There are several GUI screens that are finished. Others (most of them) are just left there as they are in 0.16. They are a combination of the new GUI styles and old ones. They sometimes look funny and out of place, but they should be functional. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
General UXUX draftUX reviewUI mockupUI reviewImplementation draftImplementation reviewFinal review
Load map
Save map
Graphics settings
Control settings
Sound settings
Interface settings
Other settings
Map generator
Quick bar Twinsen
Train GUI kovarex
Technology GUI Oxyd
Technology tooltip Oxyd
Blueprint library kovarex
Shortcut bar Oxyd
Character screen Dominik
Help overlay kovarex
Manage/Install mods Rseding
Recipe/item/Entity tooltip Twinsen
Chat icon selector ?
New game ?
Menu structure ?
Main screen chat ?
Recipe explorer ?
+

* Newly finished things since the last update in FFF-277.

Blueprint library

+

+ The blueprint library changes have been split into several steps. The reason is, that there was a big motivation to do the integration with the new quickbar (final version introduced in FFF-278) in time for 0.17.0, while the other changes can be done after. The thing with the quickbar is, that it is quite a big change to one of the most used tools in the game and people generally don't like change even when it is for the better. To minimize the hate of the change, we need to "sell it properly". By that, we should provide as many of the positive aspects of the new quickbar at the time of its introduction. +

+

+ So the change that is already implemented and working for 0.17 is the ability to put blueprints/books into the quick bar in a way that the quick bar is linked directly to the blueprint library window, so you don't need to have the physical blueprint items in your inventory. The other change is, that picking a blueprint from the blueprint library and then pressing Q will just dismiss it, instead of silently pushing it to your inventory. This works the same as the clipboard described in FFF-255. You can still explicitly insert the blueprint from the library to an inventory slot, but if you just pick it, use it, and press Q, it goes away. +

+

+ In addition to this, other changes related to the blueprint library will follow soon after 0.17.0. The first thing is the change of how the GUI looks: +

+

+ +

+

+ We will also allow to switch between grid and list view. It mainly provides a way to nicely see the longer names of the blueprint. We noticed that players try to put a large amount of info about a blueprint in its name, so we are planning to add a possibility to write a textual description of the blueprint. +

+

+ +

+

+ The last big change is to allow to put blueprint books into blueprint books, allowing better organisation. Basically like a directory structure. Whenever a blueprint/book is opened, we plan to show its current location, so the player knows exactly what is going on. +

+

+ +

+

The hand

+

+ Has it ever happened to you, that you have robots trying to put things into your full inventory, while you pick an item from it to build something, and then you just can't put it back, as the diligent robots just filled the last slot in your inventory by whatever they are trying to give to you? Wood from tree removal is the most frequent thing in my case. +

+

+ This was annoying in 0.16 from time to time, but with the new quickbar, it started to happen even more, as now, you have only one inventory, and no reserved slots in the quickbar. To solve that, we just extended the "principal" of the hand. When you pick something from the inventory, the hand icon appears on the slot. As long as you hold the thing in your cursor, the hand stays there, and prevents other things from being inserted there. This way, you should always be able to return the currently selected item into your inventory as long as you didn't get it from external source like a chest. +

+

+
+ The hand is protecting the slot from the robots. +

+

Terrain generation updates (TOGoS) +

+

Everyone has different opinions about what makes a good Factorio world. + I've been working on several changes for 0.17, but the overarching theme + has been to make the map generator options screen more intuitive + and more powerful.

+

+ This was talked about somewhat in an earlier FFF (FFF-258) regarding ore placement, + but since then we found more stuff to fix. +

+

Biter Bases

+

+ In 0.16, the size control for biter bases didn't have much effect. + The frequency control changed the frequency, but that also decreased the size of bases, + which wasn't generally what people wanted. +

+

+ For 0.17 we've reworked biter placement using a system similar to that with which we got resource placement under control. The size and frequency controls now act more like most people would expect, with frequency increasing the number of bases, and size changing the size of each base. +

+

+ +
New preview UI showing the effects of enemy base controls. + In reality the preview takes a couple seconds to regenerate after every change, + but the regeneration part is skipped in this animation to clearly show the effects of the controls. +

+

+ If you don't like the relatively uniform-across-the-world placement of biters, + there are changes under the hood to make it easier for modders to do something different. + Placement is now based on NamedNoiseExpressions "enemy-base-frequency" and "enemy-base-radius", which in turn reference "enemy-base-intensity". + By overriding any of those, a modder could easily create a map where biters are found only at high elevations, + or only near water, or correlate enemy placement with that of resources, or any other thing + that can be expressed as a function of location. +

+

Cliffs

+

+ We've added a 'continuity' control for cliffs. If you really + like mazes of cliffs, set it to high to reduce the number of gaps in cliff faces. + Or you can turn it way down to make cliffs very rare or be completely absent. +

+

+ +
Changing cliff frequency and continuity. Since cliffs are based on elevation, + you'll have to turn frequency way up if you want lots of layers + even near the starting lake. +

+

Biome Debugging

+

+ Tile placement is based on a range of humidity and 'aux' values + (humidity and aux being properties that vary at different points across the world) + that are suitable for each type of tile. For example: grass is only placed in + places with relatively high humidity, and desert (not to be confused with plain old sand) + only gets placed where aux is high. We've taken to calling these constraints 'rectangles', + because when you plot each tile's home turf on a chart of humidity and aux, + they are shown as rectangles. +

+

+ It's hard to make sense of the rectangles just by looking at the autoplace code + for each tile, so I wrote a script to chart them. This allowed us to ensure that + they were arranged as we wanted, with no gaps between them, + and with overlap in some cases. +

+

+ +
Rectangles. +

+

+ Having the humidity-aux-tile chart is all well and good, but doesn't tell the whole story, + since tile placement also depends on a noise layer specific to each tile type, + and could also influenced by user-adjustable autoplace controls (e.g. turning the grass slider up). + So to further help us visualize how humidity, aux, tile-specific noise, and + autoplace controls worked together to determine tiles on the map, + there are a couple of alternate humidity and aux generators that simply vary them + linearly from north-south and west-east, respectively. +

+

+ +
Using 'debug-moisture' and 'debug-aux' generators to drive moisture and aux, respectively. +

+

+ This map helped us realize that, rather than having controls + for each different type of tile, it made more sense to just + control moisture and aux (which is called 'terrain type' in the GUI, + because 'aux' doesn't mean anything). +

+

+ +
Sliding the moisture and aux bias sliders to make the world more or less grassy or red-deserty. +

+

+ A pet project of mine has been to + put controls in the map generator GUI so that we could select generators + for various tile properties (temperature, aux, humidity, elevation, etc) at + map-creation time without necessarily needing to involve mods. + This was useful for debugging the biome rectangles, but my ulterior + motive was to, at least in cases where there are multiple options, + show the generator information to players. A couple of reasons for + this: +

+ +

Water Placement

+

+ For 0.16 I attempted to make the shape of continents more interesting. Some people really liked the new terrain, or at least managed to find some settings that made it work for them. Others called it a "swampy mess". A common refrain was that the world was more fun to explore in the 0.12 days. +

+

+ So in 0.17 we're restoring the default elevation generator to one very similar to that used + by 0.12. Which means large, sometimes-connected lakes. +

+

+ The water 'frequency' control was confusing to a lot of people including myself. + It could be interpreted as "how much water", when the actual effect was to inversely + scale both bodies of water and continents, such that higher water frequency actually meant smaller bodies of water. + So for 0.17, the water 'frequency' and 'size' sliders are being replaced with 'scale' and 'coverage', + which do the same thing, but in a hopefully more obvious way. + Larger scale means larger land features, while more coverage means more of the map covered in water. +

+

New Map Types

+

+ In order to ensure a decent starting area, the elevation generator + always makes a plateau there (so you'll never spawn in the middle of + the ocean), and a lake (so you can get a power plant running). + Depending on what's going on outside of that plateau, this sometimes resulted in + a circular ring of cliffs around the starting point, + which looked very artificial, and we wanted to reduce that effect. +

+

+ In the process of solving that problem I created another custom generator for debugging purposes. + This one simply generated that starting area plateau in an endless ocean. + I don't actually remember how this was useful for debugging, but at one point I directed Twinsen to look at it + to illustrate the mechanics behind generating the starting area. +

+

+ The rest of the team liked that setting so much that we're making it a player-selectable option. + So in 0.17 you'll get to pick between the 'Normal' map type, which resembles that from 0.12, + and 'Island', which gives you a single large-ish island at the starting point. + There's a slider to let you change the size of the island(s). +

+

+ +

+

+ Maps with multiple starting points will have multiple islands. +

+

+ +
PvP islands! +

+

+ And speaking of scale sliders, we're expanding their range from ± a factor of 2 (the old 'very low' to 'very high' settings) + to ± a factor of 6 (shown as '17%' to '600%'). Previously the values were stored internally as one of 5 discrete options, + but as the recent terrain generation changes have made actual numeric multipliers more meaningful in most contexts + (e.g. the number of ore patches is directly proportional to the value of the 'frequency' slider, + rather than being just vaguely related to it somehow), + we're switching to storing them as numbers. + This has the side-effect that if you don't mind + editing some JSON, + you'll be able to create maps with values outside the range provided by the GUI sliders. +

+

+ Mods will be able to add their own 'map types' to the map type drop-down, too. If you really liked the shape of landmasses in 0.16 and want to be able to continue creating new maps with it, please let us know on the forum. +

+

High-res accumulators (Ernestas, Albert) +

+

+ +

+

+ The design of the accumulator has been always good. The 4 very visible cylinders, looking like giant batteries, Tesla poles and the electric beams perfectly telegraphed its function in terms of style and readability. That’s why for the high-res conversion we were very careful about keeping this entity as it was. +

+

+ The only thing that was a bit disturbing (for some) are the poles crossing to each other when more than one accumulator is placed in a row. So we decided to fix it (or break it). The rest of the work was making the entity compatible for the actual look of the game. But in essence accumulators are still the same. +

+

+ +

+

+ As always, let us know what you think on our forum. +

+ + +
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/source.html new file mode 100644 index 000000000..8e153771c --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/keep-tabular-data/source.html @@ -0,0 +1,740 @@ + + + + Friday Facts #282 - 0.17 in sight | Factorio + + + + + + + + + + + + + + + +
+ + +
+
+ +
+
+

+ Friday Facts #282 - 0.17 in sight +

+
Posted by kovarex, TOGos, Ernestas, Albert on 2019-02-15, all posts
+

+

+

The release plan (kovarex) +

+

This week was the time to close and finish all the things that will go to 0.17.0.

+

Not all of the things that we originally planned to be done were done (surprise), but we just left any non-essential stuff for later so we won't postpone the release any further. The plan is, that next week will be dedicated to the office playtesting and bugfixing. Many would argue, that we could just release instantly and let the players find the bugs for us, but we want to fix the most obvious problems in-house to avoid too many duplicate bug reports and chaos after the release. Also, some potential bugs, like save corruptions, are much more easily worked on in-house.

+

+ If the playtesting goes well, we will let you know next Friday, and if it is the case, we will aim to release the week starting 25th February. +

+

After release plan

+

+ Since there are a lot of things we would like to do before we can call 0.17 good enough, we will simply push new things into the 0.17 releases as time goes on. Even if 0.17 becomes stable in a reasonable time, we would still push things on top of it. We can still make experimental/stable version numbers inside 0.17. Most of the things shouldn't be big enough to make the game generally unstable. I've heard countless times a proposal to make small frequent releases of what have we added, this will probably be reality after 0.17 for some time. +

+

+ The smaller releases will contain mainly: +

+
    +
  • Final looks and behaviour of new GUI screens as they will be finished.
  • +
  • New graphics.
  • +
  • New sounds and sound system tweaks.
  • +
  • Mini tutorial additions and tweaks.
  • +
+

+

+ This is actually quite a large change to our procedures, and there are many ways we will be trying to maximize the effectiveness of smaller and more regular content updates. +

+

The GUI progress (kovarex) +

+

+ There are several GUI screens that are finished. Others (most of them) are just left there as they are in 0.16. They are a combination of the new GUI styles and old ones. They sometimes look funny and out of place, but they should be functional. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
General UXUX draftUX reviewUI mockupUI reviewImplementation draftImplementation reviewFinal review
Load map
Save map
Graphics settings
Control settings
Sound settings
Interface settings
Other settings
Map generator
Quick bar Twinsen
Train GUI kovarex
Technology GUI Oxyd
Technology tooltip Oxyd
Blueprint library kovarex
Shortcut bar Oxyd
Character screen Dominik
Help overlay kovarex
Manage/Install mods Rseding
Recipe/item/Entity tooltip Twinsen
Chat icon selector ?
New game ?
Menu structure ?
Main screen chat ?
Recipe explorer ?
+ * Newly finished things since the last update in FFF-277. +

Blueprint library

+

+ The blueprint library changes have been split into several steps. The reason is, that there was a big motivation to do the integration with the new quickbar (final version introduced in FFF-278) in time for 0.17.0, while the other changes can be done after. The thing with the quickbar is, that it is quite a big change to one of the most used tools in the game and people generally don't like change even when it is for the better. To minimize the hate of the change, we need to "sell it properly". By that, we should provide as many of the positive aspects of the new quickbar at the time of its introduction. +

+

+ So the change that is already implemented and working for 0.17 is the ability to put blueprints/books into the quick bar in a way that the quick bar is linked directly to the blueprint library window, so you don't need to have the physical blueprint items in your inventory. The other change is, that picking a blueprint from the blueprint library and then pressing Q will just dismiss it, instead of silently pushing it to your inventory. This works the same as the clipboard described in FFF-255. You can still explicitly insert the blueprint from the library to an inventory slot, but if you just pick it, use it, and press Q, it goes away. +

+

+ In addition to this, other changes related to the blueprint library will follow soon after 0.17.0. The first thing is the change of how the GUI looks: +

+

+ +

+

+ We will also allow to switch between grid and list view. It mainly provides a way to nicely see the longer names of the blueprint. We noticed that players try to put a large amount of info about a blueprint in its name, so we are planning to add a possibility to write a textual description of the blueprint. +

+

+ +

+

+ The last big change is to allow to put blueprint books into blueprint books, allowing better organisation. Basically like a directory structure. Whenever a blueprint/book is opened, we plan to show its current location, so the player knows exactly what is going on. +

+

+ +

+

The hand

+

+ Has it ever happened to you, that you have robots trying to put things into your full inventory, while you pick an item from it to build something, and then you just can't put it back, as the diligent robots just filled the last slot in your inventory by whatever they are trying to give to you? Wood from tree removal is the most frequent thing in my case. +

+

+ This was annoying in 0.16 from time to time, but with the new quickbar, it started to happen even more, as now, you have only one inventory, and no reserved slots in the quickbar. To solve that, we just extended the "principal" of the hand. When you pick something from the inventory, the hand icon appears on the slot. As long as you hold the thing in your cursor, the hand stays there, and prevents other things from being inserted there. This way, you should always be able to return the currently selected item into your inventory as long as you didn't get it from external source like a chest. +

+

+
+ The hand is protecting the slot from the robots. +

+

Terrain generation updates (TOGoS) +

+

Everyone has different opinions about what makes a good Factorio world. + I've been working on several changes for 0.17, but the overarching theme + has been to make the map generator options screen more intuitive + and more powerful.

+

+ This was talked about somewhat in an earlier FFF (FFF-258) regarding ore placement, + but since then we found more stuff to fix. +

+

Biter Bases

+

+ In 0.16, the size control for biter bases didn't have much effect. + The frequency control changed the frequency, but that also decreased the size of bases, + which wasn't generally what people wanted. +

+

+ For 0.17 we've reworked biter placement using a system similar to that with which we got resource placement under control. The size and frequency controls now act more like most people would expect, with frequency increasing the number of bases, and size changing the size of each base. +

+

+ +
New preview UI showing the effects of enemy base controls. + In reality the preview takes a couple seconds to regenerate after every change, + but the regeneration part is skipped in this animation to clearly show the effects of the controls. +

+

+ If you don't like the relatively uniform-across-the-world placement of biters, + there are changes under the hood to make it easier for modders to do something different. + Placement is now based on NamedNoiseExpressions "enemy-base-frequency" and "enemy-base-radius", which in turn reference "enemy-base-intensity". + By overriding any of those, a modder could easily create a map where biters are found only at high elevations, + or only near water, or correlate enemy placement with that of resources, or any other thing + that can be expressed as a function of location. +

+

Cliffs

+

+ We've added a 'continuity' control for cliffs. If you really + like mazes of cliffs, set it to high to reduce the number of gaps in cliff faces. + Or you can turn it way down to make cliffs very rare or be completely absent. +

+

+ +
Changing cliff frequency and continuity. Since cliffs are based on elevation, + you'll have to turn frequency way up if you want lots of layers + even near the starting lake. +

+

Biome Debugging

+

+ Tile placement is based on a range of humidity and 'aux' values + (humidity and aux being properties that vary at different points across the world) + that are suitable for each type of tile. For example: grass is only placed in + places with relatively high humidity, and desert (not to be confused with plain old sand) + only gets placed where aux is high. We've taken to calling these constraints 'rectangles', + because when you plot each tile's home turf on a chart of humidity and aux, + they are shown as rectangles. +

+

+ It's hard to make sense of the rectangles just by looking at the autoplace code + for each tile, so I wrote a script to chart them. This allowed us to ensure that + they were arranged as we wanted, with no gaps between them, + and with overlap in some cases. +

+

+ +
Rectangles. +

+

+ Having the humidity-aux-tile chart is all well and good, but doesn't tell the whole story, + since tile placement also depends on a noise layer specific to each tile type, + and could also influenced by user-adjustable autoplace controls (e.g. turning the grass slider up). + So to further help us visualize how humidity, aux, tile-specific noise, and + autoplace controls worked together to determine tiles on the map, + there are a couple of alternate humidity and aux generators that simply vary them + linearly from north-south and west-east, respectively. +

+

+ +
Using 'debug-moisture' and 'debug-aux' generators to drive moisture and aux, respectively. +

+

+ This map helped us realize that, rather than having controls + for each different type of tile, it made more sense to just + control moisture and aux (which is called 'terrain type' in the GUI, + because 'aux' doesn't mean anything). +

+

+ +
Sliding the moisture and aux bias sliders to make the world more or less grassy or red-deserty. +

+

+ A pet project of mine has been to + put controls in the map generator GUI so that we could select generators + for various tile properties (temperature, aux, humidity, elevation, etc) at + map-creation time without necessarily needing to involve mods. + This was useful for debugging the biome rectangles, but my ulterior + motive was to, at least in cases where there are multiple options, + show the generator information to players. A couple of reasons for + this: +

+
    +
  • It was already possible for mods to override tile property generators via presets, but + we didn't have a place to show that information in the UI. + So switching between presets could change hidden variables in non-obvious ways + and lead to a lot of confusion.
  • +
  • I had dreams of shipping alternate elevation generators in the base game.
  • +
+

Water Placement

+

+ For 0.16 I attempted to make the shape of continents more interesting. Some people really liked the new terrain, or at least managed to find some settings that made it work for them. Others called it a "swampy mess". A common refrain was that the world was more fun to explore in the 0.12 days. +

+

+ So in 0.17 we're restoring the default elevation generator to one very similar to that used + by 0.12. Which means large, sometimes-connected lakes. +

+

+ The water 'frequency' control was confusing to a lot of people including myself. + It could be interpreted as "how much water", when the actual effect was to inversely + scale both bodies of water and continents, such that higher water frequency actually meant smaller bodies of water. + So for 0.17, the water 'frequency' and 'size' sliders are being replaced with 'scale' and 'coverage', + which do the same thing, but in a hopefully more obvious way. + Larger scale means larger land features, while more coverage means more of the map covered in water. +

+

New Map Types

+

+ In order to ensure a decent starting area, the elevation generator + always makes a plateau there (so you'll never spawn in the middle of + the ocean), and a lake (so you can get a power plant running). + Depending on what's going on outside of that plateau, this sometimes resulted in + a circular ring of cliffs around the starting point, + which looked very artificial, and we wanted to reduce that effect. +

+

+ In the process of solving that problem I created another custom generator for debugging purposes. + This one simply generated that starting area plateau in an endless ocean. + I don't actually remember how this was useful for debugging, but at one point I directed Twinsen to look at it + to illustrate the mechanics behind generating the starting area. +

+

+ The rest of the team liked that setting so much that we're making it a player-selectable option. + So in 0.17 you'll get to pick between the 'Normal' map type, which resembles that from 0.12, + and 'Island', which gives you a single large-ish island at the starting point. + There's a slider to let you change the size of the island(s). +

+

+ +

+

+ Maps with multiple starting points will have multiple islands. +

+

+ +
PvP islands! +

+

+ And speaking of scale sliders, we're expanding their range from ± a factor of 2 (the old 'very low' to 'very high' settings) + to ± a factor of 6 (shown as '17%' to '600%'). Previously the values were stored internally as one of 5 discrete options, + but as the recent terrain generation changes have made actual numeric multipliers more meaningful in most contexts + (e.g. the number of ore patches is directly proportional to the value of the 'frequency' slider, + rather than being just vaguely related to it somehow), + we're switching to storing them as numbers. + This has the side-effect that if you don't mind + editing some JSON, + you'll be able to create maps with values outside the range provided by the GUI sliders. +

+

+ Mods will be able to add their own 'map types' to the map type drop-down, too. If you really liked the shape of landmasses in 0.16 and want to be able to continue creating new maps with it, please let us know on the forum. +

+

High-res accumulators (Ernestas, Albert) +

+

+ +

+

+ The design of the accumulator has been always good. The 4 very visible cylinders, looking like giant batteries, Tesla poles and the electric beams perfectly telegraphed its function in terms of style and readability. That’s why for the high-res conversion we were very careful about keeping this entity as it was. +

+

+ The only thing that was a bit disturbing (for some) are the poles crossing to each other when more than one accumulator is placed in a row. So we decided to fix it (or break it). The rest of the work was making the entity compatible for the actual look of the game. But in essence accumulators are still the same. +

+

+ +

+

+ As always, let us know what you think on our forum. +

+

+ +
+ + + + + + +
+
+ + + + + \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected-images.json new file mode 100644 index 000000000..f8a39c4bd --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected-images.json @@ -0,0 +1,12 @@ +[ + "https:\/\/miro.medium.com\/max\/1200\/1*EO-pr4RolgcAOj_Uk1rpDA.png", + "https:\/\/miro.medium.com\/fit\/c\/96\/96\/1*vFTVh_mYyf0p6m7f77A3vw.jpeg", + "https:\/\/miro.medium.com\/max\/3788\/1*5o3M5niyi911waUrKWVZ0Q.png", + "https:\/\/miro.medium.com\/max\/1994\/1*8uOdeOfnUzTaFIY1r7oAMg.png", + "https:\/\/miro.medium.com\/max\/1698\/1*e7gjTlzi55udTXbbPeEs2A.png", + "https:\/\/miro.medium.com\/max\/1508\/1*JJkRh7JihTUo2apW_9ZXAQ.png", + "https:\/\/miro.medium.com\/max\/5760\/1*6wi5BlNNnykjZs0PufrvLQ.png", + "https:\/\/miro.medium.com\/max\/1694\/1*cS9IXYGfMmgxaAUlC7oqOQ.png", + "https:\/\/miro.medium.com\/max\/1860\/1*87KlGgfbuWP38nAaQaj3xw.png", + "https:\/\/miro.medium.com\/max\/1690\/1*kfOK60PtmWx6iP681-qRcg.png" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected-metadata.json new file mode 100644 index 000000000..69d3d3b44 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Vincent Vallet", + "Direction": null, + "Excerpt": "How to run a CPU profiling with Node.js on your production in real-time and without interruption of service.", + "Image": "https:\/\/miro.medium.com\/max\/1200\/1*EO-pr4RolgcAOj_Uk1rpDA.png", + "Title": "Node.js and CPU profiling on production (in real-time without downtime)", + "SiteName": "Voodoo Engineering" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected.html new file mode 100644 index 000000000..1c98070e8 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/expected.html @@ -0,0 +1,343 @@ +
+
+

Vincent Vallet +

+ +
+

+ Why CPU monitoring is important? +

+

+ I work at Voodoo, a French company that creates mobile video games. We have a lot of challenges with performance, availability, and scalability because of the insane amount of traffic our infrastructure supports (billions of events/requests per day …… no joke!). In this setting, every metric is important and gives us a lot of information about the state of our system. +

+

+ When working with Node.js one of the most critical resources to monitor is the CPU. Most of the time, when working on a low traffic API or project we don’t realize how many simple lines of code can have a huge impact on CPU. On the other hand, when traffic increases, a simple mistake can cost dearly. +

+

+ Resources +

+

+ What kind of resources does your application need? In most cases, we focus on memory and CPU. Good monitoring of these two elements is mandatory for an application running on production. +

+

+ For memory, constant monitoring is the best practice to track the worst developer nightmare a.k.a memory leak. +

+
+
+

+

+
+
+ Memory leak in action +
+
+

+ A good way to debug memory leak is a memory dump and/or memory sampling but this is not the subject. +

+

+ (for more details about V8 and its garbage collector you can read my previous article here) +

+
+

+ Stay focused on the CPU! +

+
+

+ Most of the time we monitor this resource with a simple solution allowing us to get a graph representing CPU consumption over time. If we want to be reactive we add an alarm, based on a threshold, to warn us when CPU usage is too high. +

+
+
+

+

+
+
+ Basic CPU monitoring +
+
+

+ And what next? We don’t have data about the state of the instance when the CPU usage has increased. So we can’t determine why we had this peak, at least not without an important time of debugging, comparing log, etc. This is exactly why you need to use CPU profiling. +

+

+ CPU profiling: what’s the difference with CPU monitoring? +

+
+

+ “Most commonly, profiling information serves to aid program optimization. Profiling is achieved by instrumenting either the program source code or its binary executable form using a tool called a profiler” +

+
+

+ Basically, for Node.js, CPU profiling is nothing more than collecting data about functions which are CPU consuming. And ideally, get a graphic representation of the collected data a.k.a “flame graph” or “flame chart”. +

+

+ It will help you to track the exact file, line, and function which takes the most time to execute. +

+

+ What about existing solutions? +

+

+ Add arguments to Node.js +

+

+ Node.js provides a way to collect data about CPU with two command lines. +

+

+ The first command just executes your application, the argument just tells to V8 engine to collect data. When you stop your script all information is stored in a file. +

+
node --prof app.js
+
+
+

+

+
+
+ Output of — prof +
+
+

+ It is not very clear, is it? +

+

+ That’s why you just need to run this second command to transform your raw file into a more human-readable output. +

+
node --prof-process isolate-0xnnnnn-v8.log > processed.txt
+
+
+

+

+
+
+ The output of — prof-process +
+
+

+ It seems better, here you can determine which function consumes the most of CPU (percentage of the time). +

+

+ ClinicJs +

+

+ ClinicJs is a set of tools that allow you to collect data and display performance charts. With “clinic flame” you can generate a flame graph based on CPU consumption. +

+
+
+

+

+
+
+ Flame chart +
+
+

+ But once again, you have to stop your app, launch the tool, then terminate the script in order to display the graph (files are generated on the disk). +

+

+ For more details, you can see the project. +

+

+ To sum up, here is the list of drawbacks of the two previous solutions. +

+ +

+ In conclusion: these are good solutions to debug on development environments and/or on a local machine. +

+
+

+ Unfortunately, CPU issues have a worrying tendency to occur on production, and when you are not in front of your screen. +

+
+

+ Inspector +

+

+ “Inspector” refers to an API thanks to which you can debug your application. By debugging we mean to be able to connect directly to the core of Node.js to collect real-time data about the process. +

+

+ A module, available since version 8.x of Node.js, provides this kind of feature. There are two advantages to use it: +

+ +

+ And here is how to make a CPU profiling with this module: +

+
+ +
+

+ As you can see, all the data is returned in variable “profile”. Basically, it’s a simple JSON object representing all the call stack and the CPU consumption for each function. And if you want to use an Async/await syntax you can install the module “inspector-api”. +

+
npm install inspector-api --save
+

+ It also comes with a built-in exporter to send data to S3, with this method you don’t write anything on the disk! +

+
+ +
+

+ If you use another storage system you can just collect the data and export it by yourself. +

+
+ +
+

+ And now, CPU profiling on-demand! +

+

+ We have an API that we want to test with autocannon tool. At this step, our project is able to serve around 200 requests in 20 seconds. There is probably a mistake somewhere in the code which slows down our application. +

+
+
+

+

+
+
+

+ But now, what if we want to trigger a CPU profiling remotely (without ssh connection to the server)? It’s possible using Websocket, SSE or any other technology to send a message to your instance. +

+

+ Here is a simple example of a server using the “ws” module to send a message to a unique instance. +

+
+ +
+

+ Of course, it only works with one instance, but it’s a fake project to demonstrate the principle ;) +

+

+ Now we can request our server to ask it to send a message to our instance and start/stop a CPU profiling. In your instance, you can handle the CPU profiling like this: +

+
+ +
+

+ To sum up: we are able to trigger a CPU profiling, on-demand, in real-time, without interruption or connection to the server. Data can be collected on the disk (and extracted later) or can be sent to S3 (or any other system, PR are welcomed on the inspector-api project). +

+
+

+ And because the profiler is a part of V8 itself, the format of the generated JSON file is compatible with the Chrome dev tools. +

+
+
+

+ How can we identify an issue? +

+

+ A CPU profiling should be read like this: +

+ +

+ What does it mean? +

+

+ The larger is a box (a function call) the more it consumed CPU. So a good CPU profiling should look like a “flame” graph where each stack is the finest possible. +

+

+ In our example, every request try to generate a token. For this purpose, it calls the function pbkdf2 which is CPU consuming. Our CPU profile looks like a sequence of big blocks of time, like if the last function in the call stack takes 99% of the total time. +

+

+ The CPU profiling after optimizations, with the same time range. +

+
+
+

+

+
+
+ CPU profiling after optimizations +
+
+

+ As you can notice, we have to zoom to the profile if we want to see the call stack, because after optimizations the API was able to take a lot more traffic. Now every function in the call stack looks like a microtask. +

+
+

+ And now our application is able to serve more than 200,000 requests in 20 seconds; we increased the performance by a factor of 100k! +

+
+
+

+

+
+
+

+ More than just CPU profiling +

+

+ With the inspector module, you can do much more than just CPU profiling, here is a non-exhaustive list: +

+ +

+ Warnings +

+

+ Every tool, even the most powerful, comes with its own disadvantages. If you enable the profiler and/or the debugger on your production you have to keep an eye on two things: +

+

+ 1) performance overhead +

+

+ A profiler needs to use CPU to work and it collects data into memory. The longer you let it run and the more CPU / memory it will need. This is why you should begin with very short CPU profiling, no more than a few seconds between the start and stop command. And never forget to monitor the impact of the profiler on your own infrastructure. If everything is fine you can increase the time and the frequency of CPU profiling. +

+

+ One more very important thing: never forget to always stop a started CPU profiling. You can add a timer to automatically call the stop function after a while. +

+

+ 2) security +

+

+ Using the inspector in Node.js it’s like opening the door of the core of your application. You should be very careful about who can use features like CPU profiling and/or the debugger. Never make the inspector “public” as being able to launch a feature from an unsafe route (not protected with an authentification mechanism). Even the collected data can be seen as critical, never send it to a system you do not trust. +

+

+ Conclusion +

+

+ CPU profiling is really a must-have tool for every developer. And now, with some precautions, we can run it on production thanks to the amazing work done by the V8 and Node.js team. +

+

+ The inspector module offers a lot more features than you can use to debug your application. +

+

+ I will write another article about using CPU profiling and the inspector on production on a high traffic project. +

+

+ Sources & links +

+ +
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/source.html new file mode 100644 index 000000000..de97b17b6 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-1/source.html @@ -0,0 +1,1277 @@ + + + + + + + Node.js and CPU profiling on production (in real-time without downtime) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+

+ Node.js and CPU profiling on production (in real-time without downtime) +

+
+
+
+
+
+ Vincent Vallet +
+
+
+
+
+ Vincent Vallet +
+ +
+
+
+
+
+ Oct 18, 2019 · 8 min read +
+
+
+
+
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+
+
+
+
+
+

+ Why CPU monitoring is important? +

+

+ I work at Voodoo, a French company that creates mobile video games. We have a lot of challenges with performance, availability, and scalability because of the insane amount of traffic our infrastructure supports (billions of events/requests per day …… no joke!). In this setting, every metric is important and gives us a lot of information about the state of our system. +

+

+ When working with Node.js one of the most critical resources to monitor is the CPU. Most of the time, when working on a low traffic API or project we don’t realize how many simple lines of code can have a huge impact on CPU. On the other hand, when traffic increases, a simple mistake can cost dearly. +

+

+ Resources +

+

+ What kind of resources does your application need? In most cases, we focus on memory and CPU. Good monitoring of these two elements is mandatory for an application running on production. +

+

+ For memory, constant monitoring is the best practice to track the worst developer nightmare a.k.a memory leak. +

+
+
+
+
+
+
+ +
+
+
+
+
+
+ Memory leak in action +
+
+

+ A good way to debug memory leak is a memory dump and/or memory sampling but this is not the subject. +

+

+ (for more details about V8 and its garbage collector you can read my previous article here) +

+
+
+

+ Stay focused on the CPU! +

+
+
+

+ Most of the time we monitor this resource with a simple solution allowing us to get a graph representing CPU consumption over time. If we want to be reactive we add an alarm, based on a threshold, to warn us when CPU usage is too high. +

+
+
+
+
+
+
+ +
+
+
+
+
+
+ Basic CPU monitoring +
+
+

+ And what next? We don’t have data about the state of the instance when the CPU usage has increased. So we can’t determine why we had this peak, at least not without an important time of debugging, comparing log, etc. This is exactly why you need to use CPU profiling. +

+

+ CPU profiling: what’s the difference with CPU monitoring? +

+
+
+

+ “Most commonly, profiling information serves to aid program optimization. Profiling is achieved by instrumenting either the program source code or its binary executable form using a tool called a profiler” +

+
+
+

+ Basically, for Node.js, CPU profiling is nothing more than collecting data about functions which are CPU consuming. And ideally, get a graphic representation of the collected data a.k.a “flame graph” or “flame chart”. +

+

+ It will help you to track the exact file, line, and function which takes the most time to execute. +

+

+ What about existing solutions? +

+ +

+ Node.js provides a way to collect data about CPU with two command lines. +

+

+ The first command just executes your application, the argument just tells to V8 engine to collect data. When you stop your script all information is stored in a file. +

+
node --prof app.js
+
+
+
+
+
+
+ +
+
+
+
+
+
+ Output of — prof +
+
+

+ It is not very clear, is it? +

+

+ That’s why you just need to run this second command to transform your raw file into a more human-readable output. +

+
node --prof-process isolate-0xnnnnn-v8.log > processed.txt
+
+
+
+
+
+
+ +
+
+
+
+
+
+ The output of — prof-process +
+
+

+ It seems better, here you can determine which function consumes the most of CPU (percentage of the time). +

+ +

+ ClinicJs is a set of tools that allow you to collect data and display performance charts. With “clinic flame” you can generate a flame graph based on CPU consumption. +

+
+
+
+
+
+
+ +
+
+
+
+
+
+ Flame chart +
+
+

+ But once again, you have to stop your app, launch the tool, then terminate the script in order to display the graph (files are generated on the disk). +

+

+ For more details, you can see the project. +

+

+ To sum up, here is the list of drawbacks of the two previous solutions. +

+
    +
  • Downtime (you should kill your application to collect the data) +
  • +
  • Performance overhead +
  • +
  • Data collected locally +
  • +
  • Need external tools (ClinicJs) +
  • +
+

+ In conclusion: these are good solutions to debug on development environments and/or on a local machine. +

+
+

+ Unfortunately, CPU issues have a worrying tendency to occur on production, and when you are not in front of your screen. +

+
+

+ Inspector +

+

+ “Inspector” refers to an API thanks to which you can debug your application. By debugging we mean to be able to connect directly to the core of Node.js to collect real-time data about the process. +

+

+ A module, available since version 8.x of Node.js, provides this kind of feature. There are two advantages to use it: +

+
    +
  • it’s native (no additional installation required) +
  • +
  • it can be used programmatically (no interruption) +
  • +
+

+ And here is how to make a CPU profiling with this module: +

+
+
+
+ +
+
+
+

+ As you can see, all the data is returned in variable “profile”. Basically, it’s a simple JSON object representing all the call stack and the CPU consumption for each function. And if you want to use an Async/await syntax you can install the module “inspector-api”. +

+
npm install inspector-api --save
+

+ It also comes with a built-in exporter to send data to S3, with this method you don’t write anything on the disk! +

+
+
+
+ +
+
+
+

+ If you use another storage system you can just collect the data and export it by yourself. +

+
+
+
+ +
+
+
+

+ And now, CPU profiling on-demand! +

+

+ We have an API that we want to test with autocannon tool. At this step, our project is able to serve around 200 requests in 20 seconds. There is probably a mistake somewhere in the code which slows down our application. +

+
+
+
+
+
+
+ +
+
+
+
+
+
+

+ But now, what if we want to trigger a CPU profiling remotely (without ssh connection to the server)? It’s possible using Websocket, SSE or any other technology to send a message to your instance. +

+

+ Here is a simple example of a server using the “ws” module to send a message to a unique instance. +

+
+
+
+ +
+
+
+

+ Of course, it only works with one instance, but it’s a fake project to demonstrate the principle ;) +

+

+ Now we can request our server to ask it to send a message to our instance and start/stop a CPU profiling. In your instance, you can handle the CPU profiling like this: +

+
+
+
+ +
+
+
+

+ To sum up: we are able to trigger a CPU profiling, on-demand, in real-time, without interruption or connection to the server. Data can be collected on the disk (and extracted later) or can be sent to S3 (or any other system, PR are welcomed on the inspector-api project). +

+
+

+ And because the profiler is a part of V8 itself, the format of the generated JSON file is compatible with the Chrome dev tools. +

+
+
+
+
+
+
+
+
+
+
+
+
+ CPU profiling before optimization +
CPU profiling before optimization +
+
+
+
+
+ CPU profiling before optimization +
+
+
+
+
+
+
+

+ How can we identify an issue? +

+

+ A CPU profiling should be read like this: +

+
    +
  • the x-axis shows the stack profile population +
  • +
  • the y-axis shows stack depth +
  • +
+

+ What does it mean? +

+

+ The larger is a box (a function call) the more it consumed CPU. So a good CPU profiling should look like a “flame” graph where each stack is the finest possible. +

+

+ In our example, every request try to generate a token. For this purpose, it calls the function pbkdf2 which is CPU consuming. Our CPU profile looks like a sequence of big blocks of time, like if the last function in the call stack takes 99% of the total time. +

+

+ The CPU profiling after optimizations, with the same time range. +

+
+
+
+
+
+
+ +
+
+
+
+
+
+ CPU profiling after optimizations +
+
+

+ As you can notice, we have to zoom to the profile if we want to see the call stack, because after optimizations the API was able to take a lot more traffic. Now every function in the call stack looks like a microtask. +

+
+
+
+
+
+
+
+
+
+
+
+ CPU profiling after optimization +
CPU profiling after optimization +
+
+
+
+
+ Zoom in the CPU profiling +
+
+
+
+
+
+
+

+ And now our application is able to serve more than 200,000 requests in 20 seconds; we increased the performance by a factor of 100k! +

+
+
+
+
+
+
+ +
+
+
+
+
+
+

+ More than just CPU profiling +

+

+ With the inspector module, you can do much more than just CPU profiling, here is a non-exhaustive list: +

+
    +
  • memory dump & memory sampling +
  • +
  • code coverage +
  • +
  • use the debugger in real-time +
  • +
+

+ Warnings +

+

+ Every tool, even the most powerful, comes with its own disadvantages. If you enable the profiler and/or the debugger on your production you have to keep an eye on two things: +

+

+ 1) performance overhead +

+

+ A profiler needs to use CPU to work and it collects data into memory. The longer you let it run and the more CPU / memory it will need. This is why you should begin with very short CPU profiling, no more than a few seconds between the start and stop command. And never forget to monitor the impact of the profiler on your own infrastructure. If everything is fine you can increase the time and the frequency of CPU profiling. +

+

+ One more very important thing: never forget to always stop a started CPU profiling. You can add a timer to automatically call the stop function after a while. +

+

+ 2) security +

+

+ Using the inspector in Node.js it’s like opening the door of the core of your application. You should be very careful about who can use features like CPU profiling and/or the debugger. Never make the inspector “public” as being able to launch a feature from an unsafe route (not protected with an authentification mechanism). Even the collected data can be seen as critical, never send it to a system you do not trust. +

+

+ Conclusion +

+

+ CPU profiling is really a must-have tool for every developer. And now, with some precautions, we can run it on production thanks to the amazing work done by the V8 and Node.js team. +

+

+ The inspector module offers a lot more features than you can use to debug your application. +

+

+ I will write another article about using CPU profiling and the inspector on production on a high traffic project. +

+

+ Sources & links +

+ +
+
+
+
+
+
+
+
+
+
+
+ +

+ Voodoo Engineering +

+
+

+ Learn about Voodoo’s engineering efforts. +

+
+ +
+
+
+ +
+
+

+ +

+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+

+ Thanks to Clint FENTON.  +

+
+
+
+
+ +
+
+
+ +
+
+

+ +

+
+
+
+
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+
+
+
+
+ Vincent Vallet +
+
+

+ Written by +

+
+
+
+

+ Vincent Vallet +

+
+ +
+
+
+
+
+

+
+
+ +
+
+
+
+
+
+ Voodoo Engineering +
+
+
+

+ Voodoo Engineering +

+
+ +
+
+
+
+
+

+ Learn about Voodoo’s engineering efforts. +

+
+
+ +
+
+
+
+ +
+
+
+
+
+
+
+

+ More From Medium +

+
+
+
+
+
+
+
+
+

+ More on Nodejs from Voodoo Engineering +

+
+ +
+
+
+
+

+ More on Nodejs from Voodoo Engineering +

+
+

+ WebSockets on production with Node.js +

+
+
+
+
+
+ Vincent Vallet +
+
+ +
+ Mar 11 · 5 min read +
+
+
+
+
+
+ +
+
+

+ 42 +

+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ More on Nodejs from Voodoo Engineering +

+
+ +
+
+
+
+

+ More on Nodejs from Voodoo Engineering +

+
+

+ A successful Voodoo.io NodeJS meetup on 13th November! +

+
+
+
+
+
+ Aymeric Roffé +
+
+ +
+ Nov 20, 2019 · 3 min read +
+
+
+
+
+
+ +
+
+

+ 5 +

+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Related reads +

+
+ +
+
+ +
+
+
+
+ Andrey Pechkurov +
+
+
+ +
+
+ Dec 6, 2018 · 5 min read +
+
+
+
+
+
+ +
+
+

+ 827 +

+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch +
+
+ Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore +
+
+ Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade +
+
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected-images.json new file mode 100644 index 000000000..c85d51648 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected-images.json @@ -0,0 +1,3 @@ +[ + "https:\/\/i.kinja-img.com\/gawker-media\/image\/upload\/c_fill,f_auto,fl_progressive,g_center,h_675,pg_1,q_80,w_1200\/18zu12g5xzyxojpg.jpg" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected-metadata.json new file mode 100644 index 000000000..f1d0c6953 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Mama Robotnik", + "Direction": null, + "Excerpt": "Nothing beats the passion of a true fan writing about something they love. That's what you're about to see here: one of the richest, most amazing tributes to a great gaming series that we've ever run on Kotaku. Warning #1: this one might make your browser chug, so close your other tabs. Warning #2: This piece might make it hurt a little more than there are no new Metroid games from Nintendo on the horizon.", + "Image": "https:\/\/i.kinja-img.com\/gawker-media\/image\/upload\/c_fill,f_auto,fl_progressive,g_center,h_675,pg_1,q_80,w_1200\/18zu12g5xzyxojpg.jpg", + "Title": "The Spectacular Story Of Metroid, One Of Gaming's Richest Universes", + "SiteName": "Kotaku" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected.html new file mode 100644 index 000000000..c533fcfc9 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/expected.html @@ -0,0 +1,1108 @@ +
+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ Nothing beats the passion of a true fan writing about something they love. That's what you're about to see here: one of the richest, most amazing tributes to a great gaming series that we've ever run on Kotaku. Warning #1: this one might make your browser chug, so close your other tabs. Warning #2: This piece might make it hurt a little more than there are no new Metroid games from Nintendo on the horizon. +

+

+ Please note that this is the first half of Mama Robotnik's massive Metroid story. The second half can be found here. The entire post is a greatly-expanded version of a post that Mama Robotnik originally published on the NeoGAF forum before revising and reworking it for Kotaku. Take it away, MR... +

+ + + +

+ Nintendo’s Metroid series tells us of a malevolent and vicious universe. It’s a maelstrom in which benevolent races are routinely extinguished, and corrupt empires wage war for ownership of living weapons. +

+ + +

+ It’s a place in which xenocide is a commissioned service, and grievances are resolved with planetary apocalypses. Everything is chaotically connected to a dead race of avian prophetic poets fighting a war throughout the cosmos. It’s a dark place to visit. +

+

+ There are two purposes to this article: to explore the expansive lore of the Metroid universe – with speculation to fill in the gaps – and to exhibit some extraordinary Metroid-inspired art. All artwork is credited to its original source – follow the links to see further works of these spectacular artists. +

+ +

+ Notes on Speculation and Lore +

+

+ The games tell us much about this hostile universe, but there are a lot of unresolved story points. In response to these mysteries, the article will provide a healthy amount of speculation. You can consider the piece to be either a makeshift timeline illustrated with fan-artwork, or simply an enthusiastic attempt to reconcile the series continuity into a cohesive whole. The article is informed by the extensive research previously performed by its author. The approach taken regarding speculation is thus: The logical inclusion of probable events that resolve mysteries, while maintaining the themes of the series. +

+ +

+ Before we begin, let’s briefly revisit the five points of essential lore: +

+ + +

+ (Metroid IL Return of Samus, Metroid Prime III: Corruption and Metroid Fusion) +

+ +

+ (Metroid: Zero Mission and Metroid Prime) +

+ + +

+ (Metroid Prime EU release, Metroid Prime III: Corruption and Metroid Prime Trilogy) +

+ + +

+ (Metroid, Metroid II: Return of Samus) +

+

+ Referencing +

+

+ Each story section includes one or more of the below superscript annotations, to help inform the reader as to where the lore or speculation comes from. A brief key: +

+
+ +
+ +

+ With all that said, let us begin. +

+

+ Part One: The Wars in Heaven +

+

+ The Living Planet +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: 3ihard) +

+

+ On an unknown planet in the universe, a race of avian humanoids evolved. The species that will come to be known as the Chozo possessed great strength, agility and intelligence. The species is peaceful, and is driven by a social/religious value that nature is sacred. [M1 / MP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: 3ihard) +

+

+ Certain blessed individuals were born with a unique gift – the vague comprehension of events set to take place in the distant future. Driven by these prophecies, the race advanced quickly and became space faring. With abstract predictions of a hostile universe, the Chozo developed powered armour and armaments to defend themselves. Prepared for whatever hostility awaited them, the Chozo explored the stars. [M1 / MP / MP SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Elearia) +

+

+ The Chozo discovered that – despite their prophets’ visions of a chaotic and warring universe – the cosmos was enjoying a prolonged period of peace and enlightenment. First contact was made with a number of old and wise races, such as the Ylla, the N’kren, the Bryyonians, the Alimbic and the Luminoth. The species shared their cultures and technology, and gently colonised wild worlds such as Aether, Elysia, and Tallon IV. [MP / MPH / MP2 / MP3] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Slapshoft) +

+

+ Peace reigned through the cosmos. The alliance was a great universal renaissance, and lasted for a millennium. [MPH SP / MP2 SP / MP3 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: 3ihard) +

+

+ During this calm, the Chozo prophets continued to receive increasingly severe visions of chaos. They foresaw a universe consumed by war, horrors evolving on distant worlds, and a great toxicity waiting to be unleashed. As the visions became more precise, the species isolated itself from its allies. The Chozo civilisation became intensely driven to fight this unclear threat. [MP / MP3 SP / M2 SP /MF SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: DanilLovesFood) +

+

+ The Chozo needed more potent tools to locate this unseen and distant danger. They expanded their SkyTown colony on the gas giant Elysia and remade it into a vast interstellar observatory powered by the planet’s endless storms. The facility was of such scale that an entire species of artificial life became necessary to maintain it. The Chozo created their first species – the mechanical Elysians. [MP3 / MP3 SP] +

+ +

+ Probes were launched across the universe, and the Elysians and Chozo scrutinised the data. The search took generations, while the planet’s tempestuous atmosphere battered SkyTown, weathering the station faster than the Elysians could maintain it. After countless probe launches, a partial transmission received from a decaying and distant satellite set prophecy in motion. [MP3] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Mechanical-Hand) +

+

+ The data received was terrifying. The blue planet registered as an organism, somehow existing as both mineral and flesh. Impossible radiation pulsed from the surface, which overwhelmed the Chozo satellite and rendered it inert. The location of the planet was immediately lost, and only a broad region of space could be established. [MP3] +

+ +

+ With this find, the Chozo purpose on SkyTown was fulfilled. The race departed the facility, leaving the Elysians to continue their monitoring of the stars. The abandoned race of robots continued to launch satellites to try and rediscover the blue world, hopeful that such a discovery would herald the return of their Chozo creators. The Elysians searched unsuccessfully until Elysia’s endless storms eroded their civilisation into a rusted remnant. [MP3] +

+

+ The Chozo reconciled their vague discovery of a blue living planet with their prophecies of toxicity. On this distant world of poison, could creatures have evolved so vicious that they endangered the universe? [MP3 SP] +

+ +

+ The Invasion of Phaaze +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: 3ihard) +

+

+ Finding the exact location of the deadly planet becomes a priority for the Chozo civilisation. A gargantuan ship was assembled on the holy planet of Tallon IV, and dispatched to the dark corner of the universe where the Elysian satellite had been lost. The greatest Chozo warriors, scientists and prophets commenced a crusade for the hostile world, knowing that they would likely never make it back home. During their long journey, they conceive a name for their target: Phaaze. [MP3 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: SesakaTH) +

+

+ Generations passed, and the Chozo expedition finally located the blue planet. As they approached, they witnessed the living world as it endlessly pulsed with blue and white energies. There was nothing like this place elsewhere in the universe. [MP3 SP] +

+ +

+ Their scans confirmed their worst fears – this atmosphere was a bath of radiation and mutation – and evolution had produced horrors. [MP3 SP] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: SamusMMX) +

+

+ For billions of years, Phaaze had mutated and irradiated life that evolved on its surface. The strongest creatures had survived to thrive in an ecosystem of beautiful poison. It was then that the Chozo understood: They had arrived at the home of the most devastating and deranged creatures in the known universe. [MP3 SP] +

+ +

+ If these monsters were to escape their containment on Phaaze, they would voraciously consume their way through the cosmos. With younger races only centuries away from space travel, the Chozo could not risk them finding this world and releasing its terrors. [MP3 SP] +

+

+ The Chozo expedition came to an impasse. The threat of Phaaze’s superpredators had to be neutralised, but severe action against the planet would be sacrilege. The Chozo held life sacred, and refused to destroy the unique living world. [MP3 SP] +

+ +

+ A dangerous plan was agreed upon. The expedition ship landed on Phaaze, exposing the crew to tremendous radiation. [MP3 SP] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Adoublea) +

+

+ Chozo Warriors in power suits fought the planet’s creatures as they swarmed the ship. The soldiers battled, watching their kin die around them, in a desperate mission to buy time. [MP3 SP] +

+ +

+ The scientists within the ship began to harness the intense radiation around them, to try and engineer an artificial predator that could neutralise the planet’s superpredators. With access to the unique Phazon mutagen that covered the poisonous world, genetic engineering that should have taken decades was done in days. The Chozo engineered the first Metroid. [MP3 SP] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Methuselah3000) +

+

+ The Metroid creature was unleashed onto the planet, and the radiation caused it to reproduce quickly. The resulting swarm of Metroids began to consume the planet’s monstrosities and established themselves as Phaaze’s apex predator. [MP3 SP] +

+ +

+ The Chozo mission was complete. The worst creatures were being hunted to extinction, and the Metroids were expected to die from starvation soon after. The cost had been enormous – most of the crew had been killed defending the ship, and the survivors were deathly ill from radiation poisoning. The burnt and damaged ship took off for the long journey home, but the crew soon succumbed to the radiation they had endured. The autopilot took the ship of Chozo bodies home. [MP3 SP] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: 3ihard) +

+

+ On Phaaze, the Metroid presence lasted decades as they consumed the planet’s superpredators. The corpses of Chozo warriors were absorbed into the planet, and their battle armour slowly became weathered and scattered. The planet’s slow sentience developed an outrage that seethed under its continents. It had been violated by the Chozo. As the Metroid infestation began to die out, Phaaze developed a very primitive concept of purpose and retribution. [MP3 SP] +

+ +

+ Phaaze established a vague awareness of concepts it had absorbed from the brains of the Chozo warrior corpses – and the location of two worlds from the Chozo’s memories. As the planet entered its reproductive cycle, it purposely directed two of its seeds towards the planets Tallon IV and Aether. In the seed sent to the Chozo world, Phaaze included one of the last surviving Metroid creatures and some ruined pieces of Chozo armour, intended as a reminder of the crime Phaaze had endured at their hands. The planet sent its second seed to Aether, as the absorbed memories informed the living planet that its inhabitants were friends of the Chozo, and therefore the enemies of Phaaze. [MP 1 / MP 2 SP / MP3 SP] +

+

+ The expedition ship – heavily damaged by radiation and lack of maintenance – was guided back to civilisation by an increasingly erratic auto-pilot. After decades it eventually approached the Chozo world of Zebes, and crash-landed onto its surface. The Chozo civilisation attempted to recover data logs from the wreckage with very limited success – they were able to understand the sacrifice that the heroic crew had made, and confirmed the apparent success of the Metroids in neutralising the creatures on the living planet. The Chozo authorities were unable to establish the location of Phaaze, or recover much in the way of scientific data concerning it. [MP3 SP / SM SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Methuselah3000) +

+

+ As the Tallon IV seed began its centuries of travelling through space, the lone Metroid within absorbed vast amounts of Phazon and radiation. It became self-aware, and grew in size, intelligence and strength. It used the ruined pieces of Chozo armour to construct itself an exoskeleton, and descended into madness. The exoskeleton failed to protect the creature from the endless radiation, and the Metroid became as exotic as Phaaze’s extinct superpredators: An undying tortured genius. [MP / MP2 / MP3 / MP3 SP] +

+ +

+ The creature that would come to be known as Metroid Prime resented Phaaze for imprisoning it in the Leviathan. It resented the Chozo for creating and discarding the Metroids. It decided that it would survive, bring order to the chaotic universe that birthed it, and somehow enslave Phaaze to its will. In its solitude, immortal as a consequence of its mutations, Metroid Prime plotted its revenge against the universe. [MP / MP2 / MP3 / MP3 SP] +

+

+ The Dark Planet +

+

+ With a clear understanding of the danger of living planets, the Chozo authority commenced a search for similar threats. With far more advanced technology than their ancestors had during the Elysian era, the Chozo were unfortunate enough to find a planet of even greater horrors. [MP 3 SP / M2] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: PeaceFistArtist) +

+

+ The Chozo detected strange readings coming from a world in a desolate part of the galaxy. The planet had been previously considered so obscure and unimportant that it didn’t have a name, merely catalogued with the codename SR388 and left to its obscurity. A detailed analysis picked up some extremely strange observations; though seemingly mineral, the caverns and liquids beneath the surface shifted with metabolic rhythm – as if the whole planet was somehow a living thing. A ship was dispatched, and the strongest Chozo warriors braved the caverns beneath the surface. [M2 / M2 SP] +

+ +

+ Few made it back. They told of a cauldron of evil, an environment so hostile and vicious that it had birthed the most terrible things. [M2] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: LightningArts) +

+

+ Beneath that planet, evolution had been won by an abomination that could steal the flesh, abilities, memories and strengths of all of its prey. The creature was a fusion of energy and plasma that parasitized on life itself. With no word suitable for the nightmare they had discovered, the Chozo simply called it X. If these X-Parasites somehow gained access to the wider universe, there would be no force that could contain them. [M2] +

+ +

+ The threat had to be dealt with. Remembering the apparent success of the Chozo expedition to Phaaze, a plan was put into action. The Chozo assembled their best and brightest, their strongest and wisest. They carved their way into SR388, and dispatched mechanical creatures to construct secure facilities. Robots and Chozo warriors repressed all instances of the X-Parasite as they found them, but casualties were high. The planet appeared to fight the Chozo at every turn, it drowned the invaders in acid and unleashed ambushes of creatures. The endless swam of X-Parasites gained strength from the corpses around them. [MP3 SP / M2] +

+

+ Deep in the planet, a glass laboratory was created, its walls highly resistant to SR388’s acid belly. Here, in dangerous proximity to the X-Parasites, the Chozo scientists began their work. [M2] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: 3ihard) +

+

+ The Chozo tried to recreate the plan of their ancestors – the use of Metroids to pacify superpredators too dangerous to exist. Without access to the same planetary radiation and materials the Phaaze expedition had, progress was slow. As the war against the planet was raging around them, the Chozo scientists were able to engineer Metroids, but not a variant strong enough to overcome the X-Parasites. As more and more Chozo died protecting the laboratory, a different approach was needed. [M2 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Starshadow76) +

+

+ The Chozo succeeded in engineering a Metroid Queen, a colossal creature who would lay Metroid Hatchling eggs. When hatched, these resulting Metroids were strong and durable creatures, and finally potent enough to combat the X menace. The Chozo knew that to completely suppress the parasites, the Metroid presence on SR388 had to be permanent. To ensure that the species would not overfeed on the environment and wipe out its food chains, the scientists hardwired an instinct into the Metroid Queen’s feral mind: Only thirty-nine Metroids were to exist on the planet at any one time. This, it was hoped, would keep their numbers high enough to destroy any X re-emergence, but low enough so that they wouldn’t consume the rest of the life on the planet, and starve to death from lack of food. [M2] +

+ +

+ The scientists assembled a payload of Hatchling Eggs and the surviving Chozo warriors distributed them across the planet. The eggs hatched quickly, and the X-Parasites were immediately overwhelmed by the infant Metroids. The X-Parasites were quickly hunted to near-extinction, with only a few surviving cells entering a state of suspension deep in the planet. [M2 SP / MF] +

+

+ The Chozo had won their war, but only just. Most of the warriors and scientists had not survived, and those that were left had to make sure that the X-Parasites had been permanently suppressed. The planet shook with tremors; the earth shifted and acid poured, as if the world was trying to crush the Chozo in their glass laboratory. [M2 SP] +

+ +

+ The X-Parasites did not return, and the Metroid Queen continued to scream as her glass prison shook. The Chozo didn’t realise it, but her despair was being heard. [M2 SP] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Hermax669) +

+

+ SR388 had been violated by the Chozo. Though very different to Phaaze, SR388 had its own vague sense of awareness. It perceived the Chozo as a viral infection, and the dead X-Parasites as part of itself. It understood loss, and shook with ancient rage. [MP3 SP / M2 SP / MF SP] +

+ +

+ It changed itself to change the Metroids. It adopted them to replace the X-Parasites, and quickly killed the weaker breeds. It moved its radioactive minerals closer to their eggs and soon mutated the species. As SR388 had done with X, it did with the Metroids. It made them strong. [M2 SP / MF SP] +

+

+ Alpha, Gamma, Zeta and Omega Metroids spawned quickly, and responded to the screams of their Queen. With their bulk and strength, they smashed through the glass laboratory and slaughtered their Chozo creators. The Chozo warriors were hunted down and crushed. [M2] +

+ +

+ SR388 developed into a new cauldron of hostility. The Metroids served as the apex predator, and the robots of the Chozo decayed into machine madness and prowled the ruins, killing on sight. The Chozo mission to suppress the X-Parasite had been a success, but the planet had gained its revenge. [M2 / M2 SP / MF] +

+

+ Part Two: The End of the Renaissance +

+

+ The Holy World +

+

+ The Chozo had devastated two planets for the good of the universe, and sustained many causalities. The superpredators of Phaaze were extinct and the X-Parasites were permanently suppressed. With the crisis over, the race became consumed with a collective sense of guilt over their necessary actions. The Chozo believed the life of the universe to be sacred, and had to reconcile their aggressive actions with their faith. [MP SP / MP3 SP / M2 / MF] +

+ +

+ Worse still, their prophets continued to have visions of endless conflict and death. War was coming to the universe, and it seemed that their sins had not saved them. Many began to doubt these visions, and a schism occurred. [MP/ MP3 SP] +

+

+ The bulk of the Chozo civilisation retired themselves from galactic affairs, leaving only a few scattered colonies amongst the stars. The race retreated to the holy planet of Tallon IV, to shun their technologies and begin simpler, poetic lives. These Chozo reconnected themselves to the natural world and tried to find a harmony with it. As time went on, the most potent prophets became manic, and tried to warn their fellows of a great poison that was to come. [M1 / MP] +

+ +

+ These visions were met with increasing dismissal, but the day finally came when the prophets were believed. After eons swimming in the stars, Phaaze’s seed entered the Tallon system. [MP / MP3] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Hameed) +

+

+ The Leviathan crashed down, and rained poison and death unto the world. The impact survivors watched as their sacred nature succumbed to the mutagens leaking from the seed, and barricaded themselves in their temples as the flora and fauna transformed. Phazon spread beneath the surface of the dying planet, and radiation storms battered the surface. [MP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Source: Riivka) +

+

+ The Chozos’ punishment for their sins, and the fulfilment of Phaaze’s wrath, reached biblical proportions. The Chozo of Tallon IV did not get to rest in peace. Their life energies suffered from Phazon disruption, and upon death they became mad ghosts who screamed forever as they were torn in and out of the material world. In this purgatory, the undead immaterial Chozo murdered anyone they could find. [MP / MP3 SP] +

+ +

+ As their numbers dwindled, the last of the Chozo constructed a great temple above the impact crater. Within this temple, they used what little technology remained to project an energy field around the Leviathan to slow the spread of contagion. As the Chozo civilisation on Tallon IV was extinguished, their dying prophets told of a hero who would one day emerge, to enter the crater and defeat the evil worm within. [MP] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Source: Havoc-DM) +

+

+ Within the Impact Crater, Metroid Prime remained trapped within the Chozo energy field. In its armour constructed from ancient Chozo power suits, it continued its wait to be unleashed on the universe. [MP / MP3 SP] +

+ +

+ Dark Echoes +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: 3ihard) +

+

+ On the planet Aether, an ancient race of mystics known as the Luminoth received the horrifying data coming from Tallon IV. In distant times, the Luminoth and the Chozo had been steadfast allies – until the Chozo retreat ended their ties. Desperate to assist, the Luminoth began to organise a rescue mission. [MP2 / MP2 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: PugOfDoon) +

+

+ A dark transmission was received from Tallon IV. The image showed a screaming, ghostly Chozo figure, flickering in and out of the living universe. In its undead madness, it spoke for its kin. It raged that they would kill anyone who would set foot on their world. The planet was pandemonium, a cursed world on which the dead could not die. As the signal faded, the Luminoth realised that there was no one left alive to rescue. [MP SP / MP2 SP] +

+ +

+ The Luminoth were receiving strange readings from the devastated planet. A mutagen was spreading, unlike anything they had ever encountered. They scanned the stars for its source, and made a devastating discovery – a mass of the same mutagen was on a collision course with Aether. Phaaze’s second seed had nearly arrived at its destination. [MP2 SP / MP3 SP] +

+

+ The people of Aether turned to their technology to save them. Their planet had no native star of its own, and had been implanted millennia ago with a complex energy network that sustained all life. This system was reverently called the Light of Aether, and harnessed the light of the universe in its mechanism. The Luminoth realised that even with this great power, they could not destroy the Phazon Leviathan. A different approach was needed. [MP2 / MP2 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: SesaKath) +

+

+ The Luminoth used their great Light to engineer a small pocket universe, a dark lifeless echo of existence. The plan was bold: they would use the Light of Aether to surgically open the fabric of reality in the path of the Phazon seed, and allow it to harmlessly enter the pocket universe. If all went well, they would be saved. [MP2 SP] +

+ +

+ The day came, and the Leviathan entered Aether’s atmosphere. The Luminoth commenced their great plan. [MP2 SP] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Adriencgd) +

+

+ Phaaze’s seed was a sum of living materials beyond Luminoth comprehension. It hit the pocket universe with incalculable force, and a tsunami of exotic energy ruptured space and time. The equipment containing the dark reality lost containment within moments, and the Luminoth were helpless as their creation expanded across the entire planet. A wave of dark energy absorbed creatures, structures and land into the dark universe, and what was once a single planet – was now two. [MP2 / MP2 SP] +

+ +

+ The Luminoth surveyed the devastation. The Phazon seed was gone – it had indeed collided with the dark universe. Entire continents, with millions of inhabitants, had vanished with it. [MP2 / MP2 SP +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: AzureParagon) +

+

+ In the dark universe, a grotesque world was being born. Previous inhabitants of Aether, having been absorbed when containment of the pocket universe was lost, found themselves twisted by the corrosive new reality around them. Most perished, and their flesh fed the strange carnivorous fungi that glowed sickly colours. Some survivors were mutated by the Phazon slowly spreading beneath the surface, and adapted to survive in the hostility. [MP2 SP] +

+ +

+ Aether and its echo, the Phazon-infested Dark Aether, existed in synchronicity. As the Luminoth tried to rebuild their planet, it took only decades for cracks to form in the ether separating the two realities. As rips in the universe shattered open, Aether became a battlefield. [MP2] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Xxkiragaxx) +

+

+ A womb of Phazon mutation and dark energies had birthed a cunning and ferocious horde. The Ing erupted through the cracks between the two worlds, and commenced slaughter. They were fought back by the Luminoth, and a war began between the two parallel worlds. The Ing invaded Aether with regularity, and killed, pillaged and destroyed all that they could find. The Luminoth retaliated and crusaded into Dark Aether in their Light Suits, on suicide missions to exterminate the source of the Ing menace. Both sides suffered colossal casualties as the decades went on. [MP2] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: 3ihard) +

+

+ The war was being lost by the Luminoth. The Ing had exterminated most of their race and had stolen too many vital technologies. With the theft of essential energy components from the Light of Aether power network, they had become a defeated people. [MP2] +

+ +

+ The Ing had destroyed all of Aether’s ancient ships, and condemned the Luminoth to no escape from their doomed world. With no other choice, the survivors sealed themselves in an inner sanctum, and entered a state of suspended animation. One custodian, U-Mos, volunteered to be their guardian. As Aether became weaker and weaker, the Luminoth waited for someone to save them. They would wait a very long time. [MP2] +

+

+ The Sacrifice of the Alimbics +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Kihunter) +

+

+ As the Chozo and the Luminoth fell, so too did other ancient races. In a distant part of the universe, the Alimbics were a militaristic society that maintained peace in their galactic cluster. Their order was shattered when a murderous entity, originating from someplace beyond the understood universe, plummeted into one of their worlds. The creature emerged from the devastation as a gaseous entity, and assumed an Alimbic-styled body to begin its onslaught. [MPH] +

+ +

+ This alien juggernaut was named Gorea by the Alimbic race, and they soon understood it brought only death. Gorea killed every Alimbic it could find, and destroyed everything in its path. Planet after planet fell to Gorea, and the Alimbics realised the creature would never stop. [MPH] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Sesakath) +

+

+ The Alimbics performed an act of supreme sacrifice. They combined the mental energies of their entire race to forge a prison for Gorea. The psychic prison held it bound, and it was transplanted into an organic vessel called The Oubliette. The vessel was launched into the void outside of the universe, a course that would keep its indestructible prisoner in exile forever. The systems of the prison ship were tasked to scan the every molecule of the imprisoned Gorea, and devise an Omega weapon that could be used to kill it. [MPH / MPH SP] +

+ +

+ The mental energies expelled in this plan consumed the physical bodies of the entire Alimbic race. They vanished from the universe in an instant. Their sacrifice protected all life in the cosmos from Gorea’s murderous rampage. [MPH] +

+

+ The War of Bryyo +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Sesakath) +

+

+ As the old races of the universe died around them, the lizard people of Bryyo faced their own challenges. The Bryyonians were an advanced, space-faring race who had learned much from their Chozo allies. Their society was a deeply polarised one, with tensions eternal between the scientific and religious factions.[MP3] +

+ +

+ Over the previous centuries, the scientific agenda had dominated, with space travel proving beneficial and enlightening. As the Chozo, Luminoth and Alimbics faced extinction, the religious Bryyonians believed more than ever that the universe was a hostile place, and became desperate to stop their scientific counterparts. [MP3] +

+

+ A great war exploded across Bryyo. By its end, the scholars had been wiped out and the survivors of both sides had regressed to a feral existence. The race devolved into animals, wandering around ruins that they no longer understood. Language vanished and strength ruled. Anyone who landed on Bryyo was meat, to be killed and eaten. [MP3] +

+ +

+ The Little Rainy Planet +

+

+ The onslaught of vengeances, conquerors, poisons and politics destroyed the old races. The Alimbics had lost their flesh, while the Bryyonians had lost their souls. The Luminoth had retreated into stasis, and the Chozo of Tallon IV had been condemned to a living death. [MP / MPH / MP2 / MP3] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Kaiquesilva) +

+

+ On a small, rainy planet called Zebes, the last known Chozo colony had watched the stars with impotence. This small settlement of the nearly-extinct avian race witnessed the end of the great universal renaissance, and the slow beginning of a new chapter in galactic history. Gradually, the younger races were launching their first satellites into space. In time, new empires would rise to take the place of the old. [M1 / M1 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: 3ihard) +

+

+ Zebes prophets’ saw the visions the Chozo had always endured: great wars, spreading poison and death. And suddenly, something bold was foreseen. [M1 SP / MP3 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Fddt) +

+

+ A great hunter, clad in orange, red and green. The Chozo glimpsed a future hero, alone in the darkness beneath worlds, fighting so that good could survive evil. They saw her curing poisoned planets, and ending galactic wars. They saw the universe’s one chance to survive its apocalyptic future. They saw the only one who could defy prophecy. [M1 / MP3 SP] +

+ +

+ And they saw her wearing Chozo armour. [M1] +

+

+ Part Three: The New Empires +

+

+ The Humans +

+

+ On the planet Earth, the human race had finally developed a ship capable of leaving their solar system. A brave crew ventured into the universe to learn whether life existed elsewhere. Their discoveries fundamentally changed the human condition. On planet after planet, they found ruined tombs and cities, guarded by weathered statues of dead races. Most significant of all, they found technology. [M1 SP] +

+ +

+ The humans reverse engineered their salvage, and advanced with pace. Within another century, faster-than-light ships explored the stars, and colonies transformed hostile worlds into homes. Peaceful relations formed between other younger races, and a great Galactic Federation was founded. [M1 SP] +

+

+ The Space Pirates +

+

+ In a less hospitable region of space, a cabal of battered races joined their forces to survive. On planets where acid rain burned flesh and magma flowed, the alliance expanded into a hardened space empire. They ventured into nearby systems and took what they needed from anyone they could reach. They found the ruins of the old races and ransacked the ancient technologies within. They immersed themselves in science and unlocked the secrets of their finds. Within decades, they had advanced their spread with stronger and faster ships. The creatures enhanced themselves, rewriting their genetics and integrating mechanisms beneath their flesh. They were unique: a cybernetic race of furious murderers with a skill for patient scientific process. As more planets were invaded, their conquered civilisations were conscripted by force. [M1 SP / MP / MP3] +

+ +

+ The inevitable moment came when their Empire reached the borders of the vast Galactic Federation. [M1 SP / MP / MP3] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Mr-Corr) +

+

+ First contact was brief and furious. On that day, the warning went out to all the worlds of the Federation: Beware the Space Pirates. Though no state of war was officially declared, the empires attacked each other on sight. The Galactic Federation was large enough to repress any meaningful incursions into their space. [M1 SP / MP SP / MP3 SP / SM SP] +

+ +

+ The Massacre of Two Families +

+

+ The Galactic Federation discovered the last Chozo Colony on Zebes. The tired, ancient avians welcomed the humans and shared with them wisdom and knowledge. They offered the Galactic Federation new sciences, and taught them how to make organic computers. The Federation studied the Chozo’s own central processing unit, an engineered brain that mothered over their colony, and left with plans to assemble their own variants. On the nearest habitable planet of K-2L, a colony was established. [M1 / MP3 SP] +

+ +

+ On this world, the human Samus Aran was born. [M1] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Methuselah3000) +

+

+ Barely out of infancy, the young Samus witnessed her family die. A Space Pirate raiding party overwhelmed her colony and murdered everyone she ever knew. By staying silent while surrounded by horror, Samus survived as the Pirates ransacked the settlement and left. [M1] +

+ +

+ The Chozo colony on Zebes received K-2L’s automated distress signal. In an ancient dusty ship, they reached the planet and found Samus to be the only survivor of the massacre. The child was brought to Zebes, and the Chozo deliberated. Should she be returned to her own kind, or allowed to stay? [M1] +

+

+ Across the colony, the Prophets experienced a simultaneous moment of clarity. They understood immediately that they had found their prophesised hero. The young girl was their inheritor, and would grow strong. She would learn all she could from them, and take their strongest technologies into the universe. She would be the hero against the oncoming storm. [M1 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: R3dFiVe) +

+

+ Samus Aran reached maturity amongst the Chozo. She was trained in the combat arts of the great extinct races. She was infused with Chozo genetic material so she could employ their technologies. She was educated to be a scientist, an explorer, and a tactician. Everything that was good about the Chozo civilisation was allowed to live on in Samus. [M1] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Pyra) +

+

+ Samus became an adult, and the Chozo presented her with their greatest works: a toughened power suit and an agile spacecraft, both more potent than anything their race had ever made. The Chozo leader, decaying and blind, told Samus it was time for her to find her destiny in the universe. Samus Aran departed for the stars, and years pass. [M1 / M1 SP] +

+ +

+ As Samus tried to reconnect with her heritage on Earth, the last Chozo prophets on Zebes received a final vision: The Space Pirates were coming for them. It was time for the last Chozo to be extinguished from the universe. [M1 SP] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Phobos-Romulus) +

+

+ The Chozo hid their technologies throughout the planet, in places that they were certain Samus would find them. They concealed a second Power Suit within the walls of their holy temple, having foreseen that Samus may require it in the future. They then returned to the surface to await the inevitable. [M1 SP] +

+ +

+ The Space Pirates invaded in force, and murdered Samus Aran’s second family. The Chozo became extinct. [M1 / MP SP] +

+

+ The Mother Brain +

+

+ Space Pirate scientists arrived shortly after the carnage and focused their attention on the legendary Chozo organic central processing unit. They rewrote its benign programming and injected stimulants into its flesh. They enabled it to form an artificial intelligence obsessed with strategy and conquest. They drove its computational potential towards absolute advancement of the Space Pirate Empire. [M1 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Jaagup) +

+

+ The results went beyond High Command’s most optimistic projections. The Space Pirates had created a leader, a desperately needed figure to unite their fragmented empire. They had created their Mother Brain. The great Space Pirate generals Ridley and Kraid arrived at Zebes, ready to pay tribute to their new master and to plan for the future. Mother Brain delivered to the Space Pirates knowledge and power. She told them of a world referenced in her oldest Chozo databanks, a planet bathed in a mutagenic poison waiting to be farmed. She instructed High Command to prepare an armada of ships and invade the planet Tallon IV. [M1 / MP SP] +

+ +

+ The order was followed immediately, and the High Command discovered a world deranged by contagion. Beneath its surface, endless pools of Phazon waited to be weaponised, and a great mining operation began. Mother Brain received data from their readings on the planet; even after thousands of years, the source of the Phazon was still contained in the Chozo force field. She scrutinised her records further, and was unable to ascertain any method of breaching the barrier. The Space Pirates could retrieve the Phazon, but were denied access to its source. [MP] +

+

+ The Metroids +

+

+ A perfect storm brewed. As the Space Pirates gained access to the most potent mutagen in the universe, the Galactic Federation made an equally eventful discovery: They found the dark planet SR388. [M1 / M2] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Fireborn Form) +

+

+ A Galactic Federation survey team studied the surface, and soon encountered a gelatinous creature that swam through air. The alien defied gravity and physics as it phased through dense rock with ease. It perceived the survey team, and made a few curious chirps in their direction. It then suddenly changed temperament, aggressively charging to latch itself onto the skull of one of the party. The victim died in agony as the Metroid fed on all the energy within, and could not be removed until its prey had been reduced to a dried husk of collapsing matter. The young Metroid had just killed, in a way that science could not explain. [M1 SP / M2 SP] +

+ +

+ With effort and casualties, the scientists contained a few infant specimens of the Metroid creatures, and left the planet without further incident. [M1] +

+

+ As their vessel went back to the stars, SR388 was aware their withdrawal. It harboured a great contempt for the invaders, an endless hate fuelled by the impotence it endured centuries ago when the Chozo had committed their great invasion. The living planet had spent centuries honing the Metroids into perfect killers, and knew the devastation they could cause upon maturity. The planet had intentionally allowed the humans to take a few Metroids away so that the creatures could grow up and kill anyone out amongst the stars who ever thought of returning. SR388 took any opportunity to gain revenge against an outside universe that refused to leave it alone. [M2 SP] +

+ +

+ As the scientists began to broadcast their findings back to the Galactic Federation, Mother Brain intercepted the transmission. She cross-referenced their data with notes buried in the Chozo’s ancient fragmented records. She deduced that the Metroids were a form of genetically engineered predator of incredible power, created by the Chozo for an unknown purpose. Mother Brain ordered High Command to get the creatures to her by any means necessary. [M1 SP] +

+

+ The Space Pirates overran the Galactic Federation vessel and stole the Metroid creatures. They divided their prize: some were sent to their nearest Homeworld; others were sent to the Tallon IV outpost; and the most potent were delivered straight to Zebes for the experiments of Mother Brain. [M1 / MP / MP3] +

+ +

+ With the arrival of the first Phazon samples from Tallon IV, the exotic substance allowed the Space Pirates to slowly produce stable cloned Metroids across their breeding sites. [M1 SP / MP SP] +

+

+ The Revenge of Samus Aran +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Ojanpohja) +

+

+ In her first mission as a Bounty Hunter, Samus Arran was commissioned by the Galactic Federation to neutralise the stolen Metroids. Through careful investigation, Samus discovered that the Pirates are operating from Zebes – her home. She concluded that the Space Pirates had murdered her second family, as they had done with her first. They have took from her everyone she ever loved, and destroyed her two worlds. [M1] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Stuart Hughe) +

+

+ Samus stormed Zebes and killed everyone in her path. [M1] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Immarart) +

+

+ As her defences were breached, Mother Brain unleashed the great generals Ridley and Kraid. Both were killled, and, desperate to stop the intruder, Mother Brain released the Metroids. Samus Aran exterminated the creatures, and invaded the inner sanctum. [M1] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Twigs) +

+

+ Samus confronted the malevolent Mother Brain and blasted apart her body. A power overload was caused, and the Tourian facility shook itself apart. Samus evacuated to her ship and tried to leave Zebes, but a Space Pirate battleship in orbit registered her ascent and opened fire. Samus’ gunship plummeted back towards the Zebes and impacted Chozodia, her former home. [M1] +

+ +

+ Extremely lucky to be alive, Samus crawled out of the remains of her destroyed power suit, and fled as Space Pirate forces stormed the area. Samus hid, crawled and ran to find sanctuary in the deepest part of the Chozo’s most revered temple. [M1] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Eyes5) +

+

+ Samus found herself surrounded with murals of the dead Chozo, and accepted she was alone in the universe. Overcoming despair, she solved the trials of the Chozodian temple and a concealed power suit was revealed to her. This shining armour was even more potent than the one she had just lost, and was able to integrate the most exotic Chozo technologies. Samus realised the greater meaning of her find; the Chozo had left her gifts for her in places they had foreseen she would traverse. Her adopted family continued to protect her long after their deaths, and she would find their statues cradling survival equipment in the darkest corners of the cosmos. [M1 / MP / MP3 / M2 / SM] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Imachinivid) +

+

+ With her new armaments, Samus cleansed the Space Pirate presence from Zebes. She came to be known as “The Hunter”, and the Space Pirates learned that they will always be hunted down for what they did to her families. They fled the planet in terror. [M1 / MP / MP2 / MP3] +

+ +

+ Tallon IV +

+

+ As years passed, Samus Aran accepted further missions from the Galactic Federation. The bounty earned funded her personal vendetta against the Space Pirates. She improved her armaments, paid for black market information and stormed their outposts. Samus showed her enemies no mercy, and became the feared nemesis of their entire civilisation. With the income from her Federation services, Samus had soon amassed enough money to buy the most secret information regarding the Space Pirates: the coordinates of their stronghold on an old forgotten planet called Tallon IV. [MP1 SP] +

+ +

+ Samus guided her ship into the Tallon system and investigated an orbiting space station. She discovered a failed genetic engineering facility whose Space Pirate crew was murdered when they lost control of their own creations. Samus fought her way through the ferocious beasts scattered within, and discovered a half-insane cyborg recreation of the Space Pirate general Ridley. As the station began to collapse, the biomechanical dragon fled to the world below, and Samus pursued. [MP1] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: Lightningarts) +

+

+ Samus lost Ridley in the planet’s stormy atmosphere, and elected to land in a nearby jungle to conceal her presence from the Pirate ground forces. Exploring the surroundings, Samus discovered that the planet was once home to the bulk of the extinct Chozo civilisation. In a great temple Samus studied poetic murals that told of the Phazon comet that had struck their world. The scribblings informed her of a creature trapped deep in the comet that they referred to as “The Worm,” and of the powerful shield they erected to prevent its escape. Samus read their last prophecy; that a hero would traverse fire and ice, jungle and cave, and find twelve sacred keys that would deactivate the barrier and allow passage to the Impact Crater. This saviour from the stars would bring down the ancient shield, and destroy the worm that infected their planet. [MP1] +

+ +

+ She continued her exploration, and battled ferocious flora and fauna. The Hunter came to understand that the Space Pirates had established a complex military installation that descended far below the surface. [MP1] +

+
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+ +

+ (Artist: R-Sraven) +

+

+ Samus hunted the Pirates and accessed their computer logs. The Empire had found quantities of an intensely potent mutagen called Phazon. Laboratories across the outpost experimented with the substance, and in a short space of time they had created prototypes for the next generation of their races: powerful Phazon-fuelled juggernauts. Should these advances continue, Samus knew that the Space Pirates would be able to conquer the Galactic Federation. [MP1] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Greenstranger) +

+

+ In the most secure laboratory, Samus made a devastating discovery. The Space Pirates had used Phazon to create an army of stable clone Metroids and lost containment. The Metroid creatures were roaming the caverns deep in the planet, reproducing and mutating as the Phazon influenced their physiology. [MP1] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Ohimseeinstars) +

+

+ Samus’ final discovery was the most horrific. The powerful, poisonous Phazon was not a rare material on Tallon IV. Despite the Chozo shield containing the Impact Crater, the substance had spread and consumed the world inside-out. The core of the planet presented the Space Pirates with a vast supply of Phazon, enough to fuel their conquest of the stars. [MP1] +

+ +

+ Samus destroyed the mining facilities and laboratories, and reconstructed the twelve parts of the ancient Chozo cipher. She destroyed living weapons such as the Thardus experiment, and annihilated the prototype Omega Pirate. She overcame corrupted Metroids, and banished the tormented Chozo ghosts from the living world. She fought the mad Meta Ridley, and on his demise deactivated the Chozo containment shield. As prophesised, Samus Aran entered the Impact Crater. [MP1] +

+

+ The Worm +

+

+ Samus Aran had opened Metroid Prime’s cage, and had no understanding of what she was about to unleash on the universe. The creature had been imprisoned in a different era, and had spent eons being tortuously transformed by Phazon into an undying mad genius. [MP1] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Chrysaetos-Pteron) +

+

+ Samus and the ancient Metroid battled, and the bounty hunter shattered the creature’s metal armour. By channelling the surrounding Phazon deposits into a supercharged energy beam, Samus was able to devastate Metroid Prime’s gelatinous body. After a tremendous battle, the old creature began to collapse on itself. [MP1] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Sabretoontigers) +

+

+ Seemingly dying, Metroid Prime lashed out, grabbing a layer of material from Samus Aran’s armour. The creature melted into a pool of Phazon particles, and the bounty hunter evacuated the Impact Crater. [MP1] +

+ +

+ Samus Aran had seemingly succeeded in her mission. The surviving Space Pirates abandoned their devastated facilities and hastily evacuated the planet. With the defeat of Metroid Prime, the Phazon contagion was slowly stopping its spread. The tormented Chozo spirits that had been bound to the planet were finally able to achieve their rest. Leaving the world to recover from its devastation, Samus Aran headed back to the stars. [MP1 / MP1 SP] +

+

+ The Dark Hunter +

+

+ Metroid Prime’s exposure to millennia of Phazon had given the creature extremely exotic abilities, the most potent being its durability – to recreate itself after nearly any level of destruction. As it had collapsed on itself, the essence of Metroid Prime craved the strength and adaptability present in Samus Aran. In the Talon IV impact crater, Metroid Prime recreated itself as a dark copy of the woman who had defeated it. [MP 1 / MP2 / MP3 SP] +

+ +
+
+

Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +

+
+
+

+ (Artist: Imachinivid) +

+

+ Dark Samus clawed its way out of the Impact Crater. It departed Tallon IV to spread its venom across the stars, and to sow the seeds of a great war. [MP1 / MP2 / MP3] +

+ +

+ Click here for the second half of this epic story. +

+
+

+ Mama Robotnik is a video game historian living somewhere in the British Empire. He specialises in unearthing lost gaming media, but also enjoys a good long essay about his favourite games every now and then. He drinks a lot of tea, and has a horrendously naughty black and white cat called Blossom. If you would like to contact him, he responds to his private messages over at NeoGAF. +

+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/source.html new file mode 100644 index 000000000..0b8875271 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-2/source.html @@ -0,0 +1,3868 @@ + + + + + + + + + + The Spectacular Story Of Metroid, One Of Gaming's Richest Universes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+ + +
+
+
+ Gaming Reviews, News, Tips and More. +
+
+ +
+ +
+ Gaming Reviews, News, Tips and More. +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+ Mama Robotnik +
+ +
+
+
+
+
+ +
+ + 158 +
+
+
+
+ + +
+ 52 +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ Nothing beats the passion of a true fan writing about something they love. That's what you're about to see here: one of the richest, most amazing tributes to a great gaming series that we've ever run on Kotaku. Warning #1: this one might make your browser chug, so close your other tabs. Warning #2: This piece might make it hurt a little more than there are no new Metroid games from Nintendo on the horizon. +

+

+ Please note that this is the first half of Mama Robotnik's massive Metroid story. The second half can be found here. The entire post is a greatly-expanded version of a post that Mama Robotnik originally published on the NeoGAF forum before revising and reworking it for Kotaku. Take it away, MR... +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+ + +

+ Nintendo’s Metroid series tells us of a malevolent and vicious universe. It’s a maelstrom in which benevolent races are routinely extinguished, and corrupt empires wage war for ownership of living weapons. +

+
+ +
+
+

+ It’s a place in which xenocide is a commissioned service, and grievances are resolved with planetary apocalypses. Everything is chaotically connected to a dead race of avian prophetic poets fighting a war throughout the cosmos. It’s a dark place to visit. +

+

+ There are two purposes to this article: to explore the expansive lore of the Metroid universe – with speculation to fill in the gaps – and to exhibit some extraordinary Metroid-inspired art. All artwork is credited to its original source – follow the links to see further works of these spectacular artists. +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Notes on Speculation and Lore +

+

+ The games tell us much about this hostile universe, but there are a lot of unresolved story points. In response to these mysteries, the article will provide a healthy amount of speculation. You can consider the piece to be either a makeshift timeline illustrated with fan-artwork, or simply an enthusiastic attempt to reconcile the series continuity into a cohesive whole. The article is informed by the extensive research previously performed by its author. The approach taken regarding speculation is thus: The logical inclusion of probable events that resolve mysteries, while maintaining the themes of the series. +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Before we begin, let’s briefly revisit the five points of essential lore: +

+
    +
  • Metroids are a genetically-engineered species, created by the Chozo in the prehistory of the games. By the time the first entry begins, Metroid creatures only exist on the planet SR388. At some point long before the games, there was also a Metroid presence on the planet Phaaze. +
  • +
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Metroid IL Return of Samus, Metroid Prime III: Corruption and Metroid Fusion) +

+
    +
  • At least some Chozo possessed a native ability to see into the future. +
  • +
+

+ (Metroid: Zero Mission and Metroid Prime) +

+
    +
  • The Chozo discovered the living planet Phaaze with their Elysian Research Outpost. We are not told what transpired immediately after this discovery, but something happened that caused at least one Metroid organism to appear on Phaaze. The planet then loaded this creature – along with pieces Chozo-style powersuit armour, into a Phazon seed and launched it towards a heavily populated Chozo planet. This seed impacted Tallon IV and is contained by the Chozo within an impenetrable shield. The mutated superevolved Metroid creature within – clad in crafted power armour – is trapped in the shield until Samus Aran deactivated it thousands of years later. +
  • +
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Metroid Prime EU release, Metroid Prime III: Corruption and Metroid Prime Trilogy) +

+
    +
  • There are living planets in the Metroid Universe. Phaaze is explicitly referred to as being alive, and could interact with a sentient mind – as shown when a Galactic Federation Aurora Unit is implanted. The planet SR388 could be interpreted as having some form of sentience – it shook with apparent anger when its creatures were killed by Samus Aran, and precisely manipulated its oceans to lure the bounty hunter into hostile situations. (Metroid II: Return of Samus and Metroid Prime III: Corruption). The immediate backstory to the first game in the series is the discovery of the planet SR388. The final event of the final game in the chronology is the final destruction of SR388. +
  • +
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Metroid, Metroid II: Return of Samus) +

+

+ Referencing +

+

+ Each story section includes one or more of the below superscript annotations, to help inform the reader as to where the lore or speculation comes from. A brief key: +

+
+
+ +
+
+ +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ With all that said, let us begin. +

+

+ Part One: The Wars in Heaven +

+

+ The Living Planet +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: 3ihard) +

+

+ On an unknown planet in the universe, a race of avian humanoids evolved. The species that will come to be known as the Chozo possessed great strength, agility and intelligence. The species is peaceful, and is driven by a social/religious value that nature is sacred. [M1 / MP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: 3ihard) +

+

+ Certain blessed individuals were born with a unique gift – the vague comprehension of events set to take place in the distant future. Driven by these prophecies, the race advanced quickly and became space faring. With abstract predictions of a hostile universe, the Chozo developed powered armour and armaments to defend themselves. Prepared for whatever hostility awaited them, the Chozo explored the stars. [M1 / MP / MP SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Elearia) +

+

+ The Chozo discovered that – despite their prophets’ visions of a chaotic and warring universe – the cosmos was enjoying a prolonged period of peace and enlightenment. First contact was made with a number of old and wise races, such as the Ylla, the N’kren, the Bryyonians, the Alimbic and the Luminoth. The species shared their cultures and technology, and gently colonised wild worlds such as Aether, Elysia, and Tallon IV. [MP / MPH / MP2 / MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Slapshoft) +

+

+ Peace reigned through the cosmos. The alliance was a great universal renaissance, and lasted for a millennium. [MPH SP / MP2 SP / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: 3ihard) +

+

+ During this calm, the Chozo prophets continued to receive increasingly severe visions of chaos. They foresaw a universe consumed by war, horrors evolving on distant worlds, and a great toxicity waiting to be unleashed. As the visions became more precise, the species isolated itself from its allies. The Chozo civilisation became intensely driven to fight this unclear threat. [MP / MP3 SP / M2 SP /MF SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: DanilLovesFood) +

+

+ The Chozo needed more potent tools to locate this unseen and distant danger. They expanded their SkyTown colony on the gas giant Elysia and remade it into a vast interstellar observatory powered by the planet’s endless storms. The facility was of such scale that an entire species of artificial life became necessary to maintain it. The Chozo created their first species – the mechanical Elysians. [MP3 / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Probes were launched across the universe, and the Elysians and Chozo scrutinised the data. The search took generations, while the planet’s tempestuous atmosphere battered SkyTown, weathering the station faster than the Elysians could maintain it. After countless probe launches, a partial transmission received from a decaying and distant satellite set prophecy in motion. [MP3] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Mechanical-Hand) +

+

+ The data received was terrifying. The blue planet registered as an organism, somehow existing as both mineral and flesh. Impossible radiation pulsed from the surface, which overwhelmed the Chozo satellite and rendered it inert. The location of the planet was immediately lost, and only a broad region of space could be established. [MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ With this find, the Chozo purpose on SkyTown was fulfilled. The race departed the facility, leaving the Elysians to continue their monitoring of the stars. The abandoned race of robots continued to launch satellites to try and rediscover the blue world, hopeful that such a discovery would herald the return of their Chozo creators. The Elysians searched unsuccessfully until Elysia’s endless storms eroded their civilisation into a rusted remnant. [MP3] +

+

+ The Chozo reconciled their vague discovery of a blue living planet with their prophecies of toxicity. On this distant world of poison, could creatures have evolved so vicious that they endangered the universe? [MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Invasion of Phaaze +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: 3ihard) +

+

+ Finding the exact location of the deadly planet becomes a priority for the Chozo civilisation. A gargantuan ship was assembled on the holy planet of Tallon IV, and dispatched to the dark corner of the universe where the Elysian satellite had been lost. The greatest Chozo warriors, scientists and prophets commenced a crusade for the hostile world, knowing that they would likely never make it back home. During their long journey, they conceive a name for their target: Phaaze. [MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: SesakaTH) +

+

+ Generations passed, and the Chozo expedition finally located the blue planet. As they approached, they witnessed the living world as it endlessly pulsed with blue and white energies. There was nothing like this place elsewhere in the universe. [MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Their scans confirmed their worst fears – this atmosphere was a bath of radiation and mutation – and evolution had produced horrors. [MP3 SP] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: SamusMMX) +

+

+ For billions of years, Phaaze had mutated and irradiated life that evolved on its surface. The strongest creatures had survived to thrive in an ecosystem of beautiful poison. It was then that the Chozo understood: They had arrived at the home of the most devastating and deranged creatures in the known universe. [MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ If these monsters were to escape their containment on Phaaze, they would voraciously consume their way through the cosmos. With younger races only centuries away from space travel, the Chozo could not risk them finding this world and releasing its terrors. [MP3 SP] +

+

+ The Chozo expedition came to an impasse. The threat of Phaaze’s superpredators had to be neutralised, but severe action against the planet would be sacrilege. The Chozo held life sacred, and refused to destroy the unique living world. [MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ A dangerous plan was agreed upon. The expedition ship landed on Phaaze, exposing the crew to tremendous radiation. [MP3 SP] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Adoublea) +

+

+ Chozo Warriors in power suits fought the planet’s creatures as they swarmed the ship. The soldiers battled, watching their kin die around them, in a desperate mission to buy time. [MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The scientists within the ship began to harness the intense radiation around them, to try and engineer an artificial predator that could neutralise the planet’s superpredators. With access to the unique Phazon mutagen that covered the poisonous world, genetic engineering that should have taken decades was done in days. The Chozo engineered the first Metroid. [MP3 SP] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Methuselah3000) +

+

+ The Metroid creature was unleashed onto the planet, and the radiation caused it to reproduce quickly. The resulting swarm of Metroids began to consume the planet’s monstrosities and established themselves as Phaaze’s apex predator. [MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Chozo mission was complete. The worst creatures were being hunted to extinction, and the Metroids were expected to die from starvation soon after. The cost had been enormous – most of the crew had been killed defending the ship, and the survivors were deathly ill from radiation poisoning. The burnt and damaged ship took off for the long journey home, but the crew soon succumbed to the radiation they had endured. The autopilot took the ship of Chozo bodies home. [MP3 SP] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: 3ihard) +

+

+ On Phaaze, the Metroid presence lasted decades as they consumed the planet’s superpredators. The corpses of Chozo warriors were absorbed into the planet, and their battle armour slowly became weathered and scattered. The planet’s slow sentience developed an outrage that seethed under its continents. It had been violated by the Chozo. As the Metroid infestation began to die out, Phaaze developed a very primitive concept of purpose and retribution. [MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Phaaze established a vague awareness of concepts it had absorbed from the brains of the Chozo warrior corpses – and the location of two worlds from the Chozo’s memories. As the planet entered its reproductive cycle, it purposely directed two of its seeds towards the planets Tallon IV and Aether. In the seed sent to the Chozo world, Phaaze included one of the last surviving Metroid creatures and some ruined pieces of Chozo armour, intended as a reminder of the crime Phaaze had endured at their hands. The planet sent its second seed to Aether, as the absorbed memories informed the living planet that its inhabitants were friends of the Chozo, and therefore the enemies of Phaaze. [MP 1 / MP 2 SP / MP3 SP] +

+

+ The expedition ship – heavily damaged by radiation and lack of maintenance – was guided back to civilisation by an increasingly erratic auto-pilot. After decades it eventually approached the Chozo world of Zebes, and crash-landed onto its surface. The Chozo civilisation attempted to recover data logs from the wreckage with very limited success – they were able to understand the sacrifice that the heroic crew had made, and confirmed the apparent success of the Metroids in neutralising the creatures on the living planet. The Chozo authorities were unable to establish the location of Phaaze, or recover much in the way of scientific data concerning it. [MP3 SP / SM SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Methuselah3000) +

+

+ As the Tallon IV seed began its centuries of travelling through space, the lone Metroid within absorbed vast amounts of Phazon and radiation. It became self-aware, and grew in size, intelligence and strength. It used the ruined pieces of Chozo armour to construct itself an exoskeleton, and descended into madness. The exoskeleton failed to protect the creature from the endless radiation, and the Metroid became as exotic as Phaaze’s extinct superpredators: An undying tortured genius. [MP / MP2 / MP3 / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The creature that would come to be known as Metroid Prime resented Phaaze for imprisoning it in the Leviathan. It resented the Chozo for creating and discarding the Metroids. It decided that it would survive, bring order to the chaotic universe that birthed it, and somehow enslave Phaaze to its will. In its solitude, immortal as a consequence of its mutations, Metroid Prime plotted its revenge against the universe. [MP / MP2 / MP3 / MP3 SP] +

+

+ The Dark Planet +

+

+ With a clear understanding of the danger of living planets, the Chozo authority commenced a search for similar threats. With far more advanced technology than their ancestors had during the Elysian era, the Chozo were unfortunate enough to find a planet of even greater horrors. [MP 3 SP / M2] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: PeaceFistArtist) +

+

+ The Chozo detected strange readings coming from a world in a desolate part of the galaxy. The planet had been previously considered so obscure and unimportant that it didn’t have a name, merely catalogued with the codename SR388 and left to its obscurity. A detailed analysis picked up some extremely strange observations; though seemingly mineral, the caverns and liquids beneath the surface shifted with metabolic rhythm – as if the whole planet was somehow a living thing. A ship was dispatched, and the strongest Chozo warriors braved the caverns beneath the surface. [M2 / M2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Few made it back. They told of a cauldron of evil, an environment so hostile and vicious that it had birthed the most terrible things. [M2] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: LightningArts) +

+

+ Beneath that planet, evolution had been won by an abomination that could steal the flesh, abilities, memories and strengths of all of its prey. The creature was a fusion of energy and plasma that parasitized on life itself. With no word suitable for the nightmare they had discovered, the Chozo simply called it X. If these X-Parasites somehow gained access to the wider universe, there would be no force that could contain them. [M2] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The threat had to be dealt with. Remembering the apparent success of the Chozo expedition to Phaaze, a plan was put into action. The Chozo assembled their best and brightest, their strongest and wisest. They carved their way into SR388, and dispatched mechanical creatures to construct secure facilities. Robots and Chozo warriors repressed all instances of the X-Parasite as they found them, but casualties were high. The planet appeared to fight the Chozo at every turn, it drowned the invaders in acid and unleashed ambushes of creatures. The endless swam of X-Parasites gained strength from the corpses around them. [MP3 SP / M2] +

+

+ Deep in the planet, a glass laboratory was created, its walls highly resistant to SR388’s acid belly. Here, in dangerous proximity to the X-Parasites, the Chozo scientists began their work. [M2] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: 3ihard) +

+

+ The Chozo tried to recreate the plan of their ancestors – the use of Metroids to pacify superpredators too dangerous to exist. Without access to the same planetary radiation and materials the Phaaze expedition had, progress was slow. As the war against the planet was raging around them, the Chozo scientists were able to engineer Metroids, but not a variant strong enough to overcome the X-Parasites. As more and more Chozo died protecting the laboratory, a different approach was needed. [M2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Starshadow76) +

+

+ The Chozo succeeded in engineering a Metroid Queen, a colossal creature who would lay Metroid Hatchling eggs. When hatched, these resulting Metroids were strong and durable creatures, and finally potent enough to combat the X menace. The Chozo knew that to completely suppress the parasites, the Metroid presence on SR388 had to be permanent. To ensure that the species would not overfeed on the environment and wipe out its food chains, the scientists hardwired an instinct into the Metroid Queen’s feral mind: Only thirty-nine Metroids were to exist on the planet at any one time. This, it was hoped, would keep their numbers high enough to destroy any X re-emergence, but low enough so that they wouldn’t consume the rest of the life on the planet, and starve to death from lack of food. [M2] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The scientists assembled a payload of Hatchling Eggs and the surviving Chozo warriors distributed them across the planet. The eggs hatched quickly, and the X-Parasites were immediately overwhelmed by the infant Metroids. The X-Parasites were quickly hunted to near-extinction, with only a few surviving cells entering a state of suspension deep in the planet. [M2 SP / MF] +

+

+ The Chozo had won their war, but only just. Most of the warriors and scientists had not survived, and those that were left had to make sure that the X-Parasites had been permanently suppressed. The planet shook with tremors; the earth shifted and acid poured, as if the world was trying to crush the Chozo in their glass laboratory. [M2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The X-Parasites did not return, and the Metroid Queen continued to scream as her glass prison shook. The Chozo didn’t realise it, but her despair was being heard. [M2 SP] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Hermax669) +

+

+ SR388 had been violated by the Chozo. Though very different to Phaaze, SR388 had its own vague sense of awareness. It perceived the Chozo as a viral infection, and the dead X-Parasites as part of itself. It understood loss, and shook with ancient rage. [MP3 SP / M2 SP / MF SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ It changed itself to change the Metroids. It adopted them to replace the X-Parasites, and quickly killed the weaker breeds. It moved its radioactive minerals closer to their eggs and soon mutated the species. As SR388 had done with X, it did with the Metroids. It made them strong. [M2 SP / MF SP] +

+

+ Alpha, Gamma, Zeta and Omega Metroids spawned quickly, and responded to the screams of their Queen. With their bulk and strength, they smashed through the glass laboratory and slaughtered their Chozo creators. The Chozo warriors were hunted down and crushed. [M2] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ SR388 developed into a new cauldron of hostility. The Metroids served as the apex predator, and the robots of the Chozo decayed into machine madness and prowled the ruins, killing on sight. The Chozo mission to suppress the X-Parasite had been a success, but the planet had gained its revenge. [M2 / M2 SP / MF] +

+

+ Part Two: The End of the Renaissance +

+

+ The Holy World +

+

+ The Chozo had devastated two planets for the good of the universe, and sustained many causalities. The superpredators of Phaaze were extinct and the X-Parasites were permanently suppressed. With the crisis over, the race became consumed with a collective sense of guilt over their necessary actions. The Chozo believed the life of the universe to be sacred, and had to reconcile their aggressive actions with their faith. [MP SP / MP3 SP / M2 / MF] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Worse still, their prophets continued to have visions of endless conflict and death. War was coming to the universe, and it seemed that their sins had not saved them. Many began to doubt these visions, and a schism occurred. [MP/ MP3 SP] +

+

+ The bulk of the Chozo civilisation retired themselves from galactic affairs, leaving only a few scattered colonies amongst the stars. The race retreated to the holy planet of Tallon IV, to shun their technologies and begin simpler, poetic lives. These Chozo reconnected themselves to the natural world and tried to find a harmony with it. As time went on, the most potent prophets became manic, and tried to warn their fellows of a great poison that was to come. [M1 / MP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ These visions were met with increasing dismissal, but the day finally came when the prophets were believed. After eons swimming in the stars, Phaaze’s seed entered the Tallon system. [MP / MP3] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Hameed) +

+

+ The Leviathan crashed down, and rained poison and death unto the world. The impact survivors watched as their sacred nature succumbed to the mutagens leaking from the seed, and barricaded themselves in their temples as the flora and fauna transformed. Phazon spread beneath the surface of the dying planet, and radiation storms battered the surface. [MP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Source: Riivka) +

+

+ The Chozos’ punishment for their sins, and the fulfilment of Phaaze’s wrath, reached biblical proportions. The Chozo of Tallon IV did not get to rest in peace. Their life energies suffered from Phazon disruption, and upon death they became mad ghosts who screamed forever as they were torn in and out of the material world. In this purgatory, the undead immaterial Chozo murdered anyone they could find. [MP / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ As their numbers dwindled, the last of the Chozo constructed a great temple above the impact crater. Within this temple, they used what little technology remained to project an energy field around the Leviathan to slow the spread of contagion. As the Chozo civilisation on Tallon IV was extinguished, their dying prophets told of a hero who would one day emerge, to enter the crater and defeat the evil worm within. [MP] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Source: Havoc-DM) +

+

+ Within the Impact Crater, Metroid Prime remained trapped within the Chozo energy field. In its armour constructed from ancient Chozo power suits, it continued its wait to be unleashed on the universe. [MP / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Dark Echoes +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: 3ihard) +

+

+ On the planet Aether, an ancient race of mystics known as the Luminoth received the horrifying data coming from Tallon IV. In distant times, the Luminoth and the Chozo had been steadfast allies – until the Chozo retreat ended their ties. Desperate to assist, the Luminoth began to organise a rescue mission. [MP2 / MP2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: PugOfDoon) +

+

+ A dark transmission was received from Tallon IV. The image showed a screaming, ghostly Chozo figure, flickering in and out of the living universe. In its undead madness, it spoke for its kin. It raged that they would kill anyone who would set foot on their world. The planet was pandemonium, a cursed world on which the dead could not die. As the signal faded, the Luminoth realised that there was no one left alive to rescue. [MP SP / MP2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Luminoth were receiving strange readings from the devastated planet. A mutagen was spreading, unlike anything they had ever encountered. They scanned the stars for its source, and made a devastating discovery – a mass of the same mutagen was on a collision course with Aether. Phaaze’s second seed had nearly arrived at its destination. [MP2 SP / MP3 SP] +

+

+ The people of Aether turned to their technology to save them. Their planet had no native star of its own, and had been implanted millennia ago with a complex energy network that sustained all life. This system was reverently called the Light of Aether, and harnessed the light of the universe in its mechanism. The Luminoth realised that even with this great power, they could not destroy the Phazon Leviathan. A different approach was needed. [MP2 / MP2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: SesaKath) +

+

+ The Luminoth used their great Light to engineer a small pocket universe, a dark lifeless echo of existence. The plan was bold: they would use the Light of Aether to surgically open the fabric of reality in the path of the Phazon seed, and allow it to harmlessly enter the pocket universe. If all went well, they would be saved. [MP2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The day came, and the Leviathan entered Aether’s atmosphere. The Luminoth commenced their great plan. [MP2 SP] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Adriencgd) +

+

+ Phaaze’s seed was a sum of living materials beyond Luminoth comprehension. It hit the pocket universe with incalculable force, and a tsunami of exotic energy ruptured space and time. The equipment containing the dark reality lost containment within moments, and the Luminoth were helpless as their creation expanded across the entire planet. A wave of dark energy absorbed creatures, structures and land into the dark universe, and what was once a single planet – was now two. [MP2 / MP2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Luminoth surveyed the devastation. The Phazon seed was gone – it had indeed collided with the dark universe. Entire continents, with millions of inhabitants, had vanished with it. [MP2 / MP2 SP +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: AzureParagon) +

+

+ In the dark universe, a grotesque world was being born. Previous inhabitants of Aether, having been absorbed when containment of the pocket universe was lost, found themselves twisted by the corrosive new reality around them. Most perished, and their flesh fed the strange carnivorous fungi that glowed sickly colours. Some survivors were mutated by the Phazon slowly spreading beneath the surface, and adapted to survive in the hostility. [MP2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Aether and its echo, the Phazon-infested Dark Aether, existed in synchronicity. As the Luminoth tried to rebuild their planet, it took only decades for cracks to form in the ether separating the two realities. As rips in the universe shattered open, Aether became a battlefield. [MP2] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Xxkiragaxx) +

+

+ A womb of Phazon mutation and dark energies had birthed a cunning and ferocious horde. The Ing erupted through the cracks between the two worlds, and commenced slaughter. They were fought back by the Luminoth, and a war began between the two parallel worlds. The Ing invaded Aether with regularity, and killed, pillaged and destroyed all that they could find. The Luminoth retaliated and crusaded into Dark Aether in their Light Suits, on suicide missions to exterminate the source of the Ing menace. Both sides suffered colossal casualties as the decades went on. [MP2] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: 3ihard) +

+

+ The war was being lost by the Luminoth. The Ing had exterminated most of their race and had stolen too many vital technologies. With the theft of essential energy components from the Light of Aether power network, they had become a defeated people. [MP2] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Ing had destroyed all of Aether’s ancient ships, and condemned the Luminoth to no escape from their doomed world. With no other choice, the survivors sealed themselves in an inner sanctum, and entered a state of suspended animation. One custodian, U-Mos, volunteered to be their guardian. As Aether became weaker and weaker, the Luminoth waited for someone to save them. They would wait a very long time. [MP2] +

+

+ The Sacrifice of the Alimbics +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Kihunter) +

+

+ As the Chozo and the Luminoth fell, so too did other ancient races. In a distant part of the universe, the Alimbics were a militaristic society that maintained peace in their galactic cluster. Their order was shattered when a murderous entity, originating from someplace beyond the understood universe, plummeted into one of their worlds. The creature emerged from the devastation as a gaseous entity, and assumed an Alimbic-styled body to begin its onslaught. [MPH] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ This alien juggernaut was named Gorea by the Alimbic race, and they soon understood it brought only death. Gorea killed every Alimbic it could find, and destroyed everything in its path. Planet after planet fell to Gorea, and the Alimbics realised the creature would never stop. [MPH] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Sesakath) +

+

+ The Alimbics performed an act of supreme sacrifice. They combined the mental energies of their entire race to forge a prison for Gorea. The psychic prison held it bound, and it was transplanted into an organic vessel called The Oubliette. The vessel was launched into the void outside of the universe, a course that would keep its indestructible prisoner in exile forever. The systems of the prison ship were tasked to scan the every molecule of the imprisoned Gorea, and devise an Omega weapon that could be used to kill it. [MPH / MPH SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The mental energies expelled in this plan consumed the physical bodies of the entire Alimbic race. They vanished from the universe in an instant. Their sacrifice protected all life in the cosmos from Gorea’s murderous rampage. [MPH] +

+

+ The War of Bryyo +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Sesakath) +

+

+ As the old races of the universe died around them, the lizard people of Bryyo faced their own challenges. The Bryyonians were an advanced, space-faring race who had learned much from their Chozo allies. Their society was a deeply polarised one, with tensions eternal between the scientific and religious factions.[MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Over the previous centuries, the scientific agenda had dominated, with space travel proving beneficial and enlightening. As the Chozo, Luminoth and Alimbics faced extinction, the religious Bryyonians believed more than ever that the universe was a hostile place, and became desperate to stop their scientific counterparts. [MP3] +

+

+ A great war exploded across Bryyo. By its end, the scholars had been wiped out and the survivors of both sides had regressed to a feral existence. The race devolved into animals, wandering around ruins that they no longer understood. Language vanished and strength ruled. Anyone who landed on Bryyo was meat, to be killed and eaten. [MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Little Rainy Planet +

+

+ The onslaught of vengeances, conquerors, poisons and politics destroyed the old races. The Alimbics had lost their flesh, while the Bryyonians had lost their souls. The Luminoth had retreated into stasis, and the Chozo of Tallon IV had been condemned to a living death. [MP / MPH / MP2 / MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Kaiquesilva) +

+

+ On a small, rainy planet called Zebes, the last known Chozo colony had watched the stars with impotence. This small settlement of the nearly-extinct avian race witnessed the end of the great universal renaissance, and the slow beginning of a new chapter in galactic history. Gradually, the younger races were launching their first satellites into space. In time, new empires would rise to take the place of the old. [M1 / M1 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: 3ihard) +

+

+ Zebes prophets’ saw the visions the Chozo had always endured: great wars, spreading poison and death. And suddenly, something bold was foreseen. [M1 SP / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Fddt) +

+

+ A great hunter, clad in orange, red and green. The Chozo glimpsed a future hero, alone in the darkness beneath worlds, fighting so that good could survive evil. They saw her curing poisoned planets, and ending galactic wars. They saw the universe’s one chance to survive its apocalyptic future. They saw the only one who could defy prophecy. [M1 / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ And they saw her wearing Chozo armour. [M1] +

+

+ Part Three: The New Empires +

+

+ The Humans +

+

+ On the planet Earth, the human race had finally developed a ship capable of leaving their solar system. A brave crew ventured into the universe to learn whether life existed elsewhere. Their discoveries fundamentally changed the human condition. On planet after planet, they found ruined tombs and cities, guarded by weathered statues of dead races. Most significant of all, they found technology. [M1 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The humans reverse engineered their salvage, and advanced with pace. Within another century, faster-than-light ships explored the stars, and colonies transformed hostile worlds into homes. Peaceful relations formed between other younger races, and a great Galactic Federation was founded. [M1 SP] +

+

+ The Space Pirates +

+

+ In a less hospitable region of space, a cabal of battered races joined their forces to survive. On planets where acid rain burned flesh and magma flowed, the alliance expanded into a hardened space empire. They ventured into nearby systems and took what they needed from anyone they could reach. They found the ruins of the old races and ransacked the ancient technologies within. They immersed themselves in science and unlocked the secrets of their finds. Within decades, they had advanced their spread with stronger and faster ships. The creatures enhanced themselves, rewriting their genetics and integrating mechanisms beneath their flesh. They were unique: a cybernetic race of furious murderers with a skill for patient scientific process. As more planets were invaded, their conquered civilisations were conscripted by force. [M1 SP / MP / MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The inevitable moment came when their Empire reached the borders of the vast Galactic Federation. [M1 SP / MP / MP3] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Mr-Corr) +

+

+ First contact was brief and furious. On that day, the warning went out to all the worlds of the Federation: Beware the Space Pirates. Though no state of war was officially declared, the empires attacked each other on sight. The Galactic Federation was large enough to repress any meaningful incursions into their space. [M1 SP / MP SP / MP3 SP / SM SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Massacre of Two Families +

+

+ The Galactic Federation discovered the last Chozo Colony on Zebes. The tired, ancient avians welcomed the humans and shared with them wisdom and knowledge. They offered the Galactic Federation new sciences, and taught them how to make organic computers. The Federation studied the Chozo’s own central processing unit, an engineered brain that mothered over their colony, and left with plans to assemble their own variants. On the nearest habitable planet of K-2L, a colony was established. [M1 / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ On this world, the human Samus Aran was born. [M1] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Methuselah3000) +

+

+ Barely out of infancy, the young Samus witnessed her family die. A Space Pirate raiding party overwhelmed her colony and murdered everyone she ever knew. By staying silent while surrounded by horror, Samus survived as the Pirates ransacked the settlement and left. [M1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Chozo colony on Zebes received K-2L’s automated distress signal. In an ancient dusty ship, they reached the planet and found Samus to be the only survivor of the massacre. The child was brought to Zebes, and the Chozo deliberated. Should she be returned to her own kind, or allowed to stay? [M1] +

+

+ Across the colony, the Prophets experienced a simultaneous moment of clarity. They understood immediately that they had found their prophesised hero. The young girl was their inheritor, and would grow strong. She would learn all she could from them, and take their strongest technologies into the universe. She would be the hero against the oncoming storm. [M1 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: R3dFiVe) +

+

+ Samus Aran reached maturity amongst the Chozo. She was trained in the combat arts of the great extinct races. She was infused with Chozo genetic material so she could employ their technologies. She was educated to be a scientist, an explorer, and a tactician. Everything that was good about the Chozo civilisation was allowed to live on in Samus. [M1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Pyra) +

+

+ Samus became an adult, and the Chozo presented her with their greatest works: a toughened power suit and an agile spacecraft, both more potent than anything their race had ever made. The Chozo leader, decaying and blind, told Samus it was time for her to find her destiny in the universe. Samus Aran departed for the stars, and years pass. [M1 / M1 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ As Samus tried to reconnect with her heritage on Earth, the last Chozo prophets on Zebes received a final vision: The Space Pirates were coming for them. It was time for the last Chozo to be extinguished from the universe. [M1 SP] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Phobos-Romulus) +

+

+ The Chozo hid their technologies throughout the planet, in places that they were certain Samus would find them. They concealed a second Power Suit within the walls of their holy temple, having foreseen that Samus may require it in the future. They then returned to the surface to await the inevitable. [M1 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The Space Pirates invaded in force, and murdered Samus Aran’s second family. The Chozo became extinct. [M1 / MP SP] +

+

+ The Mother Brain +

+

+ Space Pirate scientists arrived shortly after the carnage and focused their attention on the legendary Chozo organic central processing unit. They rewrote its benign programming and injected stimulants into its flesh. They enabled it to form an artificial intelligence obsessed with strategy and conquest. They drove its computational potential towards absolute advancement of the Space Pirate Empire. [M1 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Jaagup) +

+

+ The results went beyond High Command’s most optimistic projections. The Space Pirates had created a leader, a desperately needed figure to unite their fragmented empire. They had created their Mother Brain. The great Space Pirate generals Ridley and Kraid arrived at Zebes, ready to pay tribute to their new master and to plan for the future. Mother Brain delivered to the Space Pirates knowledge and power. She told them of a world referenced in her oldest Chozo databanks, a planet bathed in a mutagenic poison waiting to be farmed. She instructed High Command to prepare an armada of ships and invade the planet Tallon IV. [M1 / MP SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ The order was followed immediately, and the High Command discovered a world deranged by contagion. Beneath its surface, endless pools of Phazon waited to be weaponised, and a great mining operation began. Mother Brain received data from their readings on the planet; even after thousands of years, the source of the Phazon was still contained in the Chozo force field. She scrutinised her records further, and was unable to ascertain any method of breaching the barrier. The Space Pirates could retrieve the Phazon, but were denied access to its source. [MP] +

+

+ The Metroids +

+

+ A perfect storm brewed. As the Space Pirates gained access to the most potent mutagen in the universe, the Galactic Federation made an equally eventful discovery: They found the dark planet SR388. [M1 / M2] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Fireborn Form) +

+

+ A Galactic Federation survey team studied the surface, and soon encountered a gelatinous creature that swam through air. The alien defied gravity and physics as it phased through dense rock with ease. It perceived the survey team, and made a few curious chirps in their direction. It then suddenly changed temperament, aggressively charging to latch itself onto the skull of one of the party. The victim died in agony as the Metroid fed on all the energy within, and could not be removed until its prey had been reduced to a dried husk of collapsing matter. The young Metroid had just killed, in a way that science could not explain. [M1 SP / M2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ With effort and casualties, the scientists contained a few infant specimens of the Metroid creatures, and left the planet without further incident. [M1] +

+

+ As their vessel went back to the stars, SR388 was aware their withdrawal. It harboured a great contempt for the invaders, an endless hate fuelled by the impotence it endured centuries ago when the Chozo had committed their great invasion. The living planet had spent centuries honing the Metroids into perfect killers, and knew the devastation they could cause upon maturity. The planet had intentionally allowed the humans to take a few Metroids away so that the creatures could grow up and kill anyone out amongst the stars who ever thought of returning. SR388 took any opportunity to gain revenge against an outside universe that refused to leave it alone. [M2 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ As the scientists began to broadcast their findings back to the Galactic Federation, Mother Brain intercepted the transmission. She cross-referenced their data with notes buried in the Chozo’s ancient fragmented records. She deduced that the Metroids were a form of genetically engineered predator of incredible power, created by the Chozo for an unknown purpose. Mother Brain ordered High Command to get the creatures to her by any means necessary. [M1 SP] +

+

+ The Space Pirates overran the Galactic Federation vessel and stole the Metroid creatures. They divided their prize: some were sent to their nearest Homeworld; others were sent to the Tallon IV outpost; and the most potent were delivered straight to Zebes for the experiments of Mother Brain. [M1 / MP / MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ With the arrival of the first Phazon samples from Tallon IV, the exotic substance allowed the Space Pirates to slowly produce stable cloned Metroids across their breeding sites. [M1 SP / MP SP] +

+

+ The Revenge of Samus Aran +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Ojanpohja) +

+

+ In her first mission as a Bounty Hunter, Samus Arran was commissioned by the Galactic Federation to neutralise the stolen Metroids. Through careful investigation, Samus discovered that the Pirates are operating from Zebes – her home. She concluded that the Space Pirates had murdered her second family, as they had done with her first. They have took from her everyone she ever loved, and destroyed her two worlds. [M1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Stuart Hughe) +

+

+ Samus stormed Zebes and killed everyone in her path. [M1] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Immarart) +

+

+ As her defences were breached, Mother Brain unleashed the great generals Ridley and Kraid. Both were killled, and, desperate to stop the intruder, Mother Brain released the Metroids. Samus Aran exterminated the creatures, and invaded the inner sanctum. [M1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Twigs) +

+

+ Samus confronted the malevolent Mother Brain and blasted apart her body. A power overload was caused, and the Tourian facility shook itself apart. Samus evacuated to her ship and tried to leave Zebes, but a Space Pirate battleship in orbit registered her ascent and opened fire. Samus’ gunship plummeted back towards the Zebes and impacted Chozodia, her former home. [M1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Extremely lucky to be alive, Samus crawled out of the remains of her destroyed power suit, and fled as Space Pirate forces stormed the area. Samus hid, crawled and ran to find sanctuary in the deepest part of the Chozo’s most revered temple. [M1] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Eyes5) +

+

+ Samus found herself surrounded with murals of the dead Chozo, and accepted she was alone in the universe. Overcoming despair, she solved the trials of the Chozodian temple and a concealed power suit was revealed to her. This shining armour was even more potent than the one she had just lost, and was able to integrate the most exotic Chozo technologies. Samus realised the greater meaning of her find; the Chozo had left her gifts for her in places they had foreseen she would traverse. Her adopted family continued to protect her long after their deaths, and she would find their statues cradling survival equipment in the darkest corners of the cosmos. [M1 / MP / MP3 / M2 / SM] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Imachinivid) +

+

+ With her new armaments, Samus cleansed the Space Pirate presence from Zebes. She came to be known as “The Hunter”, and the Space Pirates learned that they will always be hunted down for what they did to her families. They fled the planet in terror. [M1 / MP / MP2 / MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Tallon IV +

+

+ As years passed, Samus Aran accepted further missions from the Galactic Federation. The bounty earned funded her personal vendetta against the Space Pirates. She improved her armaments, paid for black market information and stormed their outposts. Samus showed her enemies no mercy, and became the feared nemesis of their entire civilisation. With the income from her Federation services, Samus had soon amassed enough money to buy the most secret information regarding the Space Pirates: the coordinates of their stronghold on an old forgotten planet called Tallon IV. [MP1 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Samus guided her ship into the Tallon system and investigated an orbiting space station. She discovered a failed genetic engineering facility whose Space Pirate crew was murdered when they lost control of their own creations. Samus fought her way through the ferocious beasts scattered within, and discovered a half-insane cyborg recreation of the Space Pirate general Ridley. As the station began to collapse, the biomechanical dragon fled to the world below, and Samus pursued. [MP1] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: Lightningarts) +

+

+ Samus lost Ridley in the planet’s stormy atmosphere, and elected to land in a nearby jungle to conceal her presence from the Pirate ground forces. Exploring the surroundings, Samus discovered that the planet was once home to the bulk of the extinct Chozo civilisation. In a great temple Samus studied poetic murals that told of the Phazon comet that had struck their world. The scribblings informed her of a creature trapped deep in the comet that they referred to as “The Worm,” and of the powerful shield they erected to prevent its escape. Samus read their last prophecy; that a hero would traverse fire and ice, jungle and cave, and find twelve sacred keys that would deactivate the barrier and allow passage to the Impact Crater. This saviour from the stars would bring down the ancient shield, and destroy the worm that infected their planet. [MP1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ She continued her exploration, and battled ferocious flora and fauna. The Hunter came to understand that the Space Pirates had established a complex military installation that descended far below the surface. [MP1] +

+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ (Artist: R-Sraven) +

+

+ Samus hunted the Pirates and accessed their computer logs. The Empire had found quantities of an intensely potent mutagen called Phazon. Laboratories across the outpost experimented with the substance, and in a short space of time they had created prototypes for the next generation of their races: powerful Phazon-fuelled juggernauts. Should these advances continue, Samus knew that the Space Pirates would be able to conquer the Galactic Federation. [MP1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Greenstranger) +

+

+ In the most secure laboratory, Samus made a devastating discovery. The Space Pirates had used Phazon to create an army of stable clone Metroids and lost containment. The Metroid creatures were roaming the caverns deep in the planet, reproducing and mutating as the Phazon influenced their physiology. [MP1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Ohimseeinstars) +

+

+ Samus’ final discovery was the most horrific. The powerful, poisonous Phazon was not a rare material on Tallon IV. Despite the Chozo shield containing the Impact Crater, the substance had spread and consumed the world inside-out. The core of the planet presented the Space Pirates with a vast supply of Phazon, enough to fuel their conquest of the stars. [MP1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Samus destroyed the mining facilities and laboratories, and reconstructed the twelve parts of the ancient Chozo cipher. She destroyed living weapons such as the Thardus experiment, and annihilated the prototype Omega Pirate. She overcame corrupted Metroids, and banished the tormented Chozo ghosts from the living world. She fought the mad Meta Ridley, and on his demise deactivated the Chozo containment shield. As prophesised, Samus Aran entered the Impact Crater. [MP1] +

+

+ The Worm +

+

+ Samus Aran had opened Metroid Prime’s cage, and had no understanding of what she was about to unleash on the universe. The creature had been imprisoned in a different era, and had spent eons being tortuously transformed by Phazon into an undying mad genius. [MP1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Chrysaetos-Pteron) +

+

+ Samus and the ancient Metroid battled, and the bounty hunter shattered the creature’s metal armour. By channelling the surrounding Phazon deposits into a supercharged energy beam, Samus was able to devastate Metroid Prime’s gelatinous body. After a tremendous battle, the old creature began to collapse on itself. [MP1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Sabretoontigers) +

+

+ Seemingly dying, Metroid Prime lashed out, grabbing a layer of material from Samus Aran’s armour. The creature melted into a pool of Phazon particles, and the bounty hunter evacuated the Impact Crater. [MP1] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Samus Aran had seemingly succeeded in her mission. The surviving Space Pirates abandoned their devastated facilities and hastily evacuated the planet. With the defeat of Metroid Prime, the Phazon contagion was slowly stopping its spread. The tormented Chozo spirits that had been bound to the planet were finally able to achieve their rest. Leaving the world to recover from its devastation, Samus Aran headed back to the stars. [MP1 / MP1 SP] +

+

+ The Dark Hunter +

+

+ Metroid Prime’s exposure to millennia of Phazon had given the creature extremely exotic abilities, the most potent being its durability – to recreate itself after nearly any level of destruction. As it had collapsed on itself, the essence of Metroid Prime craved the strength and adaptability present in Samus Aran. In the Talon IV impact crater, Metroid Prime recreated itself as a dark copy of the woman who had defeated it. [MP 1 / MP2 / MP3 SP] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+
+
+ +
+
+ Illustration for article titled The Spectacular Story Of emMetroid/em, One Of Gamings Richest Universes +
+
+
+
+

+ (Artist: Imachinivid) +

+

+ Dark Samus clawed its way out of the Impact Crater. It departed Tallon IV to spread its venom across the stars, and to sow the seeds of a great war. [MP1 / MP2 / MP3] +

+
+
+
+
+ Advertisement +
+
+
+
+
+
+

+ Click here for the second half of this epic story. +

+
+

+ Mama Robotnik is a video game historian living somewhere in the British Empire. He specialises in unearthing lost gaming media, but also enjoys a good long essay about his favourite games every now and then. He drinks a lot of tea, and has a horrendously naughty black and white cat called Blossom. If you would like to contact him, he responds to his private messages over at NeoGAF. +

+
+
+
+

+ Share This Story +

+ +
+
+

+ Get our newsletter +

+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected-images.json new file mode 100644 index 000000000..140777678 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected-images.json @@ -0,0 +1,4 @@ +[ + "https:\/\/p3-juejin.byteimg.com\/tos-cn-i-k3u1fbpfcp\/0579d17015b145a88dd93992c6447d7d~tplv-k3u1fbpfcp-watermark.jpg", + "https:\/\/p3-juejin.byteimg.com\/tos-cn-i-k3u1fbpfcp\/0579d17015b145a88dd93992c6447d7d~tplv-k3u1fbpfcp-watermark.png" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected-metadata.json new file mode 100644 index 000000000..60bd1f2db --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": null, + "Image": null, + "Title": "Lazy Load with Alt includes jpg\/png\/webp extensions", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected.html new file mode 100644 index 000000000..9016e8583 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/expected.html @@ -0,0 +1,8 @@ +
+
+

Test Case 1

+ performance.jpg +

Test Case 2

+ performance.jpg +
+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/source.html new file mode 100644 index 000000000..b4a3df858 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/lazy-image-3/source.html @@ -0,0 +1,21 @@ + + + + + Lazy Load with Alt includes jpg/png/webp extensions + + +
+

Test Case 1

+ performance.jpg +

Test Case 2

+ performance.jpg +
+ + \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected-images.json new file mode 100644 index 000000000..45552803a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected-images.json @@ -0,0 +1,4 @@ +[ + "https:\/\/cdn1.medicalnewstoday.com\/content\/images\/headlines\/318\/318674\/hand-holding-brain-lightbulb.jpg", + "https:\/\/cdn1.medicalnewstoday.com\/content\/images\/articles\/318\/318674\/hand-holding-brain-lightbulb.jpg" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected-metadata.json new file mode 100644 index 000000000..7b3947e63 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "By Ana Sandoiu", + "Direction": null, + "Excerpt": "New research investigates the neurobiological timing of the so-called a-ha! moment that occurs we have come up with the solution to a complex problem.", + "Image": "https:\/\/cdn1.medicalnewstoday.com\/content\/images\/headlines\/318\/318674\/hand-holding-brain-lightbulb.jpg", + "Title": "How does the brain turn unconscious information into conscious thought?", + "SiteName": "Medical News Today" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected.html new file mode 100644 index 000000000..18ab009e4 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/expected.html @@ -0,0 +1,102 @@ +
+
+ Neuroscience tells us that most of the work done by our brains happens on an unconscious level, but when does that "a-ha!" moment occur? And what happens during it? New research investigates. +
+

hand holding brain lightbulb
+ A new study investigates when the 'a-ha!' moment takes place in the brain, and how similar it is to other brain processes. +

+

+ Many of us have noticed that we seem to get our best ideas when we're in the shower, or that we can find the answer to a difficult question when we least think about it. +

+

+ A large body of neuroscientific studies has pointed out that the brain does a lot of work in its spare time, the so-called idle state - wherein the brain does not appear to be thinking about anything at all - and that this is the time when it works at its hardest to find solutions to complex problems. +

+

+ With time and advances in neuroscience, it has become more and more clear to researchers that Freud was right and the mind, as well as the brain, do work unconsciously. In fact, it would be safe to say that what is consciously known to us is just the tip of a much larger iceberg, deeply submerged in unconscious waters. +

+

+ But the exact moment at which information becomes known to us - or when the "tip of the iceberg" pierces through the water, and the unconscious becomes conscious - has been somewhat of a mystery, from a neuroscientific point of view. +

+

+ In other words, we do not yet know when that intellectually satisfying "a-ha!" moment takes place, or what the biology is behind it. This is why a team of researchers at Columbia University in New York City, NY, set out to investigate this moment in more detail. +

+ +

+ The scientists were led by Michael Shadlen, Ph.D., of Columbia University's Mortimer B. Zuckerman Mind Brain Behavior Institute, and the findings were published in the journal Current Biology. +

+ +

+ The hypothesis +

+

+ Dr. Shadlen and colleagues started out from an interesting hypothesis, one which they derived from previous research on the neurobiological processes involved in decision-making. +

+

+ As the authors explain, research conducted in both monkeys and humans shows that many of our decisions take place at a point when the brain "feels" as though it has gathered enough information, or when a critical level of information has been accumulated. +

+ +

+ This process of making a decision once the brain has accumulated enough evidence bears the name of "bounded evidence accumulation." Reaching this threshold is important because, although the brain does not use all of the information available, it uses as much as is necessary to make a speedy yet accurate decision. +

+

+ The researchers wondered whether or not this threshold is also responsible for our "eureka!" moments. +

+ +

+ In Dr. Shadlen's words, "Could the moment when the brain believes it has accumulated enough evidence be tied to the person's awareness of having decided - that important 'a-ha!' moment?" +

+ +

+ Examining the 'a-ha!' moment +

+

+ To answer this question, the scientists asked five people to perform a "direction discrimination" task. In it, the participants looked at dots on a computer screen. The dots moved randomly, as grains of sand would when blown by the wind. The participants were asked to say in which direction the dots had moved. +

+

+ The moment they "decided" which direction the dots seemed to be taking was considered to be the equivalent of the "a-ha!" moment. +

+

+ In the center of the screen, there was a fixed point and a clock. The display also had two "choice targets" - namely, left or right - and these were the directions in which the participants had to decide that the dots had moved. +

+

+ Shortly after the dots had stopped moving, the participants used an electronic, hand-held stylus to move the cursor in the direction that they thought the dots had moved. +

+

+ To determine when the decision was made, the researchers used the technique called "mental chronometry" - that is, after they made their decision, the participants were asked to move the clock backward to the point when they felt that they had consciously done so. +

+ +

+ "The moment in time indicated by the participants - this mental chronometry - was entirely subjective; it relied solely on their own estimation of how long it took them to make that decision," Dr. Shadlen says. "And because it was purely subjective, in principle it ought to be unverifiable." +

+ +

+ 'A-ha' moment similar to making a decision +

+

+ However, by applying a mathematical model, the scientists were able to match these subjective decision times to the bounded evidence accumulation process. +

+

+ The subjective decision times fit so well with what the scientists determined as the evidence accumulation threshold that they were able to predict the choices of four of the five participants. +

+

+ "If the time reported to us by the participants was valid, we reasoned that it might be possible to predict the accuracy of the decision," explains Dr. Shadlen. +

+

+ "We incorporated a kind of mathematical trick, based on earlier studies, which showed that the speed and accuracy of decisions were tied together by the same brain function." This "mathematical trick" was the evidence accumulation model. +

+
+

+ "Essentially, the act of becoming consciously aware of a decision conforms to the same process that the brain goes through to complete a decision, even a simple one - such as whether to turn left or right." +

+

+ Michael Shadlen, Ph.D. +

+
+

+ In other words, the study shows that the conscious awareness of the "a-ha!" moment takes place precisely when the brain has reached that threshold of evidence accumulation. +

+

+ The findings provide unique insights into the biology of consciousness, say the researchers, and they bring us closer to understanding the biological basis of decisions, ethics, and, generally, the human mind. +

+ +
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/source.html new file mode 100644 index 000000000..8a014599f --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/medicalnewstoday/source.html @@ -0,0 +1,2012 @@ + + + + + + + How does the brain turn unconscious information into conscious thought? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + +
+
+ +
+ +
+
+
+ +
+
+
+ + + + + + + + + + +
+ + +
+ + + + + + +
+
+
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected-metadata.json new file mode 100644 index 000000000..d998fb4c7 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": "Contents", + "Image": null, + "Title": "Shared Mutable History \u2014 evolve extension for Mercurial", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected.html new file mode 100644 index 000000000..61915e455 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/expected.html @@ -0,0 +1,738 @@ +
+ + +

+ Once you have mastered the art of mutable history in a single repository (see the user guide), you can move up to the next level: shared mutable history. evolve lets you push and pull draft changesets between repositories along with their obsolescence markers. This opens up a number of interesting possibilities. +

+

+ The simplest scenario is a single developer working across two computers. Say you’re working on code that must be tested on a remote test server, probably in a rack somewhere, only accessible by SSH, and running an “enterprise-grade” (out-of-date) OS. But you probably prefer to write code locally: everything is setup the way you like it, and you can use your preferred editor, IDE, merge/diff tools, etc. +

+

+ Traditionally, your options are limited: either +

+
+
+
    +
  • (ab)use your source control system by committing half-working code in order to get it onto the remote test server, or +
  • +
  • go behind source control’s back by using rsync (or similar) to transfer your code back-and-forth until it is ready to commit +
  • +
+
+
+

+ The former is less bad with distributed version control systems like Mercurial, but it’s still far from ideal. (One important version control “best practice” is that every commit should make things just a little bit better, i.e. you should never commit code that is worse than what came before.) The latter, avoiding version control entirely, means that you’re walking a tightrope without a safety net. One accidental rsync in the wrong direction could destroy hours of work. +

+

+ Using Mercurial with evolve to share mutable history solves these problems. As with single-repository evolve, you can commit whenever the code is demonstrably better, even if all the tests aren’t passing yet—just hg amend when they are. And you can transfer those half-baked changesets between repositories to try things out on your test server before anything is carved in stone. +

+

+ A less common scenario is multiple developers sharing mutable history, typically for code review. We’ll cover this scenario later. First, we will cover single-user sharing. +

+
+

+ Sharing with a single developer +

+
+

+ Publishing and non-publishing repositories +

+

+ The key to shared mutable history is to keep your changesets in draft phase as you pass them around. Recall that by default, hg push promotes changesets from draft to public, and public changesets are immutable. You can change this behaviour by reconfiguring the remote repository so that it is non-publishing. (Short version: set phases.publish to false. Long version follows.) +

+
+
+

+ Setting up +

+

+ We’ll work through an example with three local repositories, although in the real world they’d most likely be on three different computers. First, the public repository is where tested, polished changesets live, and it is where you synchronize with the rest of your team. +

+ +

+ We’ll need two clones where work gets done, test-repo and dev-repo: +

+
+
$ hg clone public test-repo
+updating to branch default
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ hg clone test-repo dev-repo
+updating to branch default
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+

+ dev-repo is your local machine, with GUI merge tools and IDEs and everything configured just the way you like it. test-repo is the test server in a rack somewhere behind SSH. So for the most part, we’ll develop in dev-repo, push to test-repo, test and polish there, and push to public. +

+

+ The key to shared mutable history is to make the target repository, in this case test-repo, non-publishing. And, of course, we have to enable the evolve extension in both test-repo and dev-repo. +

+

+ First, edit the configuration for test-repo: +

+
+
$ hg -R test-repo config --edit --local
+
+
+

+ and add +

+
+
[phases]
+publish = false
+
+[extensions]
+evolve =
+
+
+

+ Then edit the configuration for dev-repo: +

+
+
$ hg -R dev-repo config --edit --local
+
+
+

+ and add +

+ +

+ Keep in mind that in real life, these repositories would probably be on separate computers, so you’d have to login to each one to configure each repository. +

+

+ To start things off, let’s make one public, immutable changeset: +

+
+
$ cd test-repo
+$ echo 'my new project' > file1
+$ hg add file1
+$ hg commit -m 'create new project'
+$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files
+
+
+

+ and pull that into the development repository: +

+
+
$ cd ../dev-repo
+$ hg pull -u
+[...]
+added 1 changesets with 1 changes to 1 files
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+
+ +
+

+ Example 2: Amend again, locally +

+

+ This process can repeat. Perhaps you figure out a more elegant fix to the bug, and want to mutate history so nobody ever knows you had a less-than-perfect idea. We’ll implement it locally in dev-repo and push to test-repo: +

+
+
$ echo 'Fix, fix, and fix.' > file1
+$ hg amend
+$ hg push
+
+
+

+ This time around, the temporary amend commit is in dev-repo, and it is not transferred to test-repo—the same as before, just in the opposite direction. Figure 4 shows the two repositories after amending in dev-repo and pushing to test-repo. +

+
+

+ [figure SG04: each repo has one temporary amend commit, but they’re different in each one] +

+
+

+ Let’s hop over to test-repo to test the more elegant fix: +

+
+
$ cd ../test-repo
+$ hg update
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+

+ This time, all the tests pass, so no further amending is required. This bug fix is finished, so we push it to the public repository: +

+
+
$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files
+
+
+

+ Note that only one changeset—the final version, after two amendments—was actually pushed. Again, Mercurial doesn’t transfer hidden changesets on push and pull. +

+

+ So the picture in public is much simpler than in either dev-repo or test-repo. Neither of our missteps nor our amendments are publicly visible, just the final, beautifully polished changeset: +

+
+

+ [figure SG05: public repo with rev 0:0dc9, 1:de61, both public] +

+
+

+ There is one important step left to do. Because we pushed from test-repo to public, the pushed changeset is in public phase in those two repositories. But dev-repo has been out-of-the-loop; changeset de61 is still draft there. If we’re not careful, we might mutate history in dev-repo, obsoleting a changeset that is already public. Let’s avoid that situation for now by pushing up to dev-repo: +

+
+
$ hg push ../dev-repo
+pushing to ../dev-repo
+searching for changes
+no changes found
+
+
+

+ Even though no changesets were pushed, Mercurial still pushed obsolescence markers and phase changes to dev-repo. +

+

+ A final note: since this fix is now public, it is immutable. It’s no longer possible to amend it: +

+
+
$ hg amend -m 'fix bug 37'
+abort: cannot amend public changesets
+
+
+

+ This is, after all, the whole point of Mercurial’s phases: to prevent rewriting history that has already been published. +

+
+
+
+

+ Sharing with multiple developers: code review +

+

+ Now that you know how to share your own mutable history across multiple computers, you might be wondering if it makes sense to share mutable history with others. It does, but you have to be careful, stay alert, and communicate with your peers. +

+

+ Code review is a good use case for sharing mutable history across multiple developers: Alice commits a draft changeset, submits it for review, and amends her changeset until her reviewer is satisfied. Meanwhile, Bob is also committing draft changesets for review, amending until his reviewer is satisfied. Once a particular changeset passes review, the respective author (Alice or Bob) pushes it to the public (publishing) repository. +

+

+ Incidentally, the reviewers here can be anyone: maybe Bob and Alice review each other’s work; maybe the same third party reviews both; or maybe they pick different experts to review their work on different parts of a large codebase. Similarly, it doesn’t matter if reviews are conducted in person, by email, or by carrier pigeon. Code review is outside of the scope of Mercurial, so all we’re looking at here is the mechanics of committing, amending, pushing, and pulling. +

+
+

+ Setting up +

+

+ To demonstrate, let’s start with the public repository as we left it in the last example, with two immutable changesets (figure 5 above). We’ll clone a review repository from it, and then Alice and Bob will both clone from review. +

+
+
$ hg clone public review
+updating to branch default
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ hg clone review alice
+updating to branch default
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ hg clone review bob
+updating to branch default
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+

+ We need to configure Alice’s and Bob’s working repositories to enable evolve. First, edit Alice’s configuration with +

+
+
$ hg -R alice config --edit --local
+
+
+

+ and add +

+ +

+ Then edit Bob’s repository configuration: +

+
+
$ hg -R bob config --edit --local
+
+
+

+ and add the same text. +

+
+
+

+ Example 3: Alice commits and amends a draft fix +

+

+ We’ll follow Alice working on a bug fix. We’re going to use bookmarks to make it easier to understand multiple branch heads in the review repository, so Alice starts off by creating a bookmark and committing her first attempt at a fix: +

+
+
$ hg bookmark bug15
+$ echo 'fix' > file2
+$ hg commit -A -u alice -m 'fix bug 15 (v1)'
+adding file2
+
+
+

+ Note the unorthodox “(v1)” in the commit message. We’re just using that to make this tutorial easier to follow; it’s not something we’d recommend in real life. +

+

+ Of course Alice wouldn’t commit unless her fix worked to her satisfaction, so it must be time to solicit a code review. She does this by pushing to the review repository: +

+
+
$ hg push -B bug15
+[...]
+added 1 changesets with 1 changes to 1 files
+exporting bookmark bug15
+
+
+

+ (The use of -B is important to ensure that we only push the bookmarked head, and that the bookmark itself is pushed. See this guide to bookmarks, especially the Sharing Bookmarks section, if you’re not familiar with bookmarks.) +

+

+ Some time passes, and Alice receives her code review. As a result, Alice revises her fix and submits it for a second review: +

+
+
$ echo 'Fix.' > file2
+$ hg amend -m 'fix bug 15 (v2)'
+$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+updating bookmark bug15
+
+
+

+ Figure 6 shows the state of the review repository at this point. +

+
+

+ [figure SG06: rev 2:fn1e is Alice’s obsolete v1, rev 3:cbdf is her v2; both children of rev 1:de61] +

+
+

+ After a busy morning of bug fixing, Alice stops for lunch. Let’s see what Bob has been up to. +

+
+
+

+ Example 4: Bob implements and publishes a new feature +

+

+ Meanwhile, Bob has been working on a new feature. Like Alice, he’ll use a bookmark to track his work, and he’ll push that bookmark to the review repository, so that reviewers know which changesets to review. +

+
+
$ cd ../bob
+$ echo 'stuff' > file1
+$ hg bookmark featureX
+$ hg commit -u bob -m 'implement feature X (v1)'          # rev 4:1636
+$ hg push -B featureX
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+exporting bookmark featureX
+
+
+

+ When Bob receives his code review, he improves his implementation a bit, amends, and submits the resulting changeset for review: +

+
+
$ echo 'do stuff' > file1
+$ hg amend -m 'implement feature X (v2)'                  # rev 5:0eb7
+$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+updating bookmark featureX
+
+
+

+ Unfortunately, that still doesn’t pass muster. Bob’s reviewer insists on proper capitalization and punctuation. +

+
+
$ echo 'Do stuff.' > file1
+$ hg amend -m 'implement feature X (v3)'                  # rev 6:540b
+
+
+

+ On the bright side, the second review said, “Go ahead and publish once you fix that.” So Bob immediately publishes his third attempt: +

+
+
$ hg push ../public
+[...]
+added 1 changesets with 1 changes to 1 files
+
+
+

+ It’s not enough just to update public, though! Other people also use the review repository, and right now it doesn’t have Bob’s latest amendment (“v3”, revision 6:540b), nor does it know that the precursor of that changeset (“v2”, revision 5:0eb7) is obsolete. Thus, Bob pushes to review as well: +

+
+
$ hg push ../review
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+updating bookmark featureX
+
+
+

+ Figure 7 shows the result of Bob’s work in both review and public. +

+
+

+ [figure SG07: review includes Alice’s draft work on bug 15, as well as Bob’s v1, v2, and v3 changes for feature X: v1 and v2 obsolete, v3 public. public contains only the final, public implementation of feature X] +

+
+

+ Incidentally, it’s important that Bob push to public before review. If he pushed to review first, then revision 6:540b would still be in draft phase in review, but it would be public in both Bob’s local repository and the public repository. That could lead to confusion at some point, which is easily avoided by pushing first to public. +

+
+
+

+ Example 5: Alice integrates and publishes +

+

+ Finally, Alice gets back from lunch and sees that the carrier pigeon with her second review has arrived (or maybe it’s in her email inbox). Alice’s reviewer approved her amended changeset, so she pushes it to public: +

+
+
$ hg push ../public
+[...]
+remote has heads on branch 'default' that are not known locally: 540ba8f317e6
+abort: push creates new remote head cbdfbd5a5db2!
+(pull and merge or see "hg help push" for details about pushing new heads)
+
+
+

+ Oops! Bob has won the race to push first to public. So Alice needs to integrate with Bob: let’s pull his changeset(s) and see what the branch heads are. +

+
+
$ hg pull ../public
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+(run 'hg heads' to see heads, 'hg merge' to merge)
+$ hg log -G -q -r 'head()' --template '{rev}:{node|short}  ({author})\n'
+o  5:540ba8f317e6  (bob)
+|
+| @  4:cbdfbd5a5db2  (alice)
+|/
+
+
+

+ We’ll assume Alice and Bob are perfectly comfortable with rebasing changesets. (After all, they’re already using mutable history in the form of amend.) So Alice rebases her changeset on top of Bob’s and publishes the result: +

+
+
$ hg rebase -d 5
+$ hg push ../public
+[...]
+added 1 changesets with 1 changes to 1 files
+$ hg push ../review
+[...]
+added 1 changesets with 0 changes to 0 files
+updating bookmark bug15
+
+
+

+ The result, in both review and public repositories, is shown in figure 8. +

+
+

+ [figure SG08: review shows v1 and v2 of Alice’s fix, then v1, v2, v3 of Bob’s feature, finally Alice’s fix rebased onto Bob’s. public just shows the final public version of each changeset] +

+
+
+
+
+

+ Getting into trouble with shared mutable history +

+

+ Mercurial with evolve is a powerful tool, and using powerful tools can have consequences. (You can cut yourself badly with a sharp knife, but every competent chef keeps several around. Ever try to chop onions with a spoon?) +

+

+ In the user guide, we saw examples of unstbale changesets, which are the most common type of troubled changeset. (Recall that a non-obsolete changeset with obsolete ancestors is an orphan.) +

+

+ Two other types of troubles can happen: divergent and bumped changesets. Both are more likely with shared mutable history, especially mutable history shared by multiple developers. +

+
+

+ Setting up +

+

+ For these examples, we’re going to use a slightly different workflow: as before, Alice and Bob share a public repository. But this time there is no review repository. Instead, Alice and Bob put on their cowboy hats, throw good practice to the wind, and pull directly from each other’s working repositories. +

+

+ So we throw away everything except public and reclone: +

+
+
$ rm -rf review alice bob
+$ hg clone public alice
+updating to branch default
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ hg clone public bob
+updating to branch default
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+

+ Once again we have to configure their repositories: enable evolve and (since Alice and Bob will be pulling directly from each other) make their repositories non-publishing. Edit Alice’s configuration: +

+
+
$ hg -R alice config --edit --local
+
+
+

+ and add +

+
+
[extensions]
+rebase =
+evolve =
+
+[phases]
+publish = false
+
+
+

+ Then edit Bob’s repository configuration: +

+
+
$ hg -R bob config --edit --local
+
+
+

+ and add the same text. +

+
+
+

+ Example 6: Divergent changesets +

+

+ When an obsolete changeset has two successors, those successors are divergent. One way to get into such a situation is by failing to communicate with your teammates. Let’s see how that might happen. +

+

+ First, we’ll have Bob commit a bug fix that could still be improved: +

+
+
$ cd bob
+$ echo 'pretty good fix' >> file1
+$ hg commit -u bob -m 'fix bug 24 (v1)'                   # rev 4:2fe6
+
+
+

+ Since Alice and Bob are now in cowboy mode, Alice pulls Bob’s draft changeset and amends it herself. +

+
+
$ cd ../alice
+$ hg pull -u ../bob
+[...]
+added 1 changesets with 1 changes to 1 files
+$ echo 'better fix (alice)' >> file1
+$ hg amend -u alice -m 'fix bug 24 (v2 by alice)'
+
+
+

+ But Bob has no idea that Alice just did this. (See how important good communication is?) So he implements a better fix of his own: +

+
+
$ cd ../bob
+$ echo 'better fix (bob)' >> file1
+$ hg amend -u bob -m 'fix bug 24 (v2 by bob)'             # rev 6:a360
+
+
+

+ At this point, the divergence exists, but only in theory: Bob’s original changeset, 4:2fe6, is obsolete and has two successors. But those successors are in different repositories, so the trouble is not visible to anyone yet. It will be as soon as Bob pulls from Alice’s repository (or vice-versa). +

+
+
$ hg pull ../alice
+[...]
+added 1 changesets with 1 changes to 2 files (+1 heads)
+(run 'hg heads' to see heads, 'hg merge' to merge)
+2 new divergent changesets
+
+
+

+ Figure 9 shows the situation in Bob’s repository. +

+
+

+ [figure SG09: Bob’s repo with 2 heads for the 2 divergent changesets, 6:a360 and 7:e3f9; wc is at 6:a360; both are successors of obsolete 4:2fe6, hence divergence] +

+
+

+ Now we need to get out of trouble. As usual, the answer is to evolve history. +

+
+
$ HGMERGE=internal:other hg evolve
+merge:[6] fix bug 24 (v2 by bob)
+with: [7] fix bug 24 (v2 by alice)
+base: [4] fix bug 24 (v1)
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+
+
+

+ Figure 10 shows how Bob’s repository looks now. +

+
+

+ [figure SG10: only one visible head, 9:5ad6, successor to hidden 6:a360 and 7:e3f9] +

+
+

+ We carefully dodged a merge conflict by specifying a merge tool (internal:other) that will take Alice’s changes over Bob’s. (You might wonder why Bob wouldn’t prefer his own changes by using internal:local. He’s avoiding a bug in evolve that occurs when evolving divergent changesets using internal:local.) +

+

+ # XXX this link does not work .. bug: https://bitbucket.org/marmoute/mutable-history/issue/48/ +

+

+ ** STOP HERE: WORK IN PROGRESS ** +

+
+
+

+ Phase-divergence: when a rewritten changeset is made public +

+

+ If Alice and Bob are collaborating on some mutable changesets, it’s possible to get into a situation where an otherwise worthwhile changeset cannot be pushed to the public repository; it is phase-divergent with another changeset that was made public first. Let’s demonstrate one way this could happen. +

+

+ It starts with Alice committing a bug fix. Right now, we don’t yet know if this bug fix is good enough to push to the public repository, but it’s good enough for Alice to commit. +

+
+
$ cd alice
+$ echo 'fix' > file2
+$ hg commit -A -m 'fix bug 15'
+adding file2
+
+
+

+ Now Bob has a bad idea: he decides to pull whatever Alice is working on and tweak her bug fix to his taste: +

+
+
$ cd ../bob
+$ hg pull -u ../alice
+[...]
+added 1 changesets with 1 changes to 1 files
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ echo 'Fix.' > file2
+$ hg amend -A -m 'fix bug 15 (amended)'
+
+
+

+ (Note the lack of communication between Alice and Bob. Failing to communicate with your colleagues is a good way to get into trouble. Nevertheless, evolve can usually sort things out, as we will see.) +

+
+

+ [figure SG06: Bob’s repo with one amendment] +

+
+

+ After some testing, Alice realizes her bug fix is just fine as it is: no need for further polishing and amending, this changeset is ready to publish. +

+
+
$ cd ../alice
+$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files
+
+
+

+ This introduces a contradiction: in Bob’s repository, changeset 2:e011 (his copy of Alice’s fix) is obsolete, since Bob amended it. But in Alice’s repository (and the public repository), that changeset is public: it is immutable, carved in stone for all eternity. No changeset can be both obsolete and public, so Bob is in for a surprise the next time he pulls from public: +

+
+
$ cd ../bob
+$ hg pull -q -u
+1 new phase-divergent changesets
+
+
+

+ Figure 7 shows what just happened to Bob’s repository: changeset 2:e011 is now public, so it can’t be obsolete. When that changeset was obsolete, it made perfect sense for it to have a successor, namely Bob’s amendment of Alice’s fix (changeset 4:fe88). But it’s illogical for a public changeset to have a successor, so 4:fe88 is troubled: it has become bumped. +

+
+

+ [figure SG07: 2:e011 now public not obsolete, 4:fe88 now bumped] +

+
+

+ As usual when there’s trouble in your repository, the solution is to evolve it: +

+ +

+ Figure 8 illustrates Bob’s repository after evolving away the bumped changeset. Ignoring the obsolete changesets, Bob now has a nice, clean, simple history. His amendment of Alice’s bug fix lives on, as changeset 5:227d—albeit with a software-generated commit message. (Bob should probably amend that changeset to improve the commit message.) But the important thing is that his repository no longer has any troubled changesets, thanks to evolve. +

+
+

+ [figure SG08: 5:227d is new, formerly bumped changeset 4:fe88 now hidden] +

+
+
+
+
+

+ Conclusion +

+

+ Mutable history is a powerful tool. Like a sharp knife, an experienced user can do wonderful things with it, much more wonderful than with a dull knife (never mind a rusty spoon). At the same time, an inattentive or careless user can do harm to himself or others. Mercurial with evolve goes to great lengths to limit the harm you can do by trying to handle all possible types of “troubled” changesets. Nevertheless, having a first-aid kit nearby does not mean you should stop being careful with sharp knives. +

+

+ Mutable history shared across multiple repositories by a single developer is a natural extension of this model. Once you are used to using a single sharp knife on its own, it’s pretty straightforward to chop onions and mushrooms using the same knife, or to alternate between two chopping boards with different knives. +

+

+ Mutable history shared by multiple developers is a scary place to go. Imagine a professional kitchen full of expert chefs tossing their favourite knives back and forth, with the occasional axe or chainsaw thrown in to spice things up. If you’re confident that you and your colleagues can do it without losing a limb, go for it. But be sure to practice a lot first before you rely on it! +

+
+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/source.html new file mode 100644 index 000000000..e8dc6f642 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/mercurial/source.html @@ -0,0 +1,979 @@ + + + + + + Evolve: Shared Mutable History — evolve extension for Mercurial + + + + + + + + + + + + + +
+

+ evolve extension for Mercurial +

+

+ Evolve: Shared Mutable History +

+
+
+

+ «  Evolve: User Guide   ::   Contents   ::   Evolve: Concepts  » +

+
+
+
+

+ Evolve: Shared Mutable History +

+ +

+ Once you have mastered the art of mutable history in a single repository (see the user guide), you can move up to the next level: shared mutable history. evolve lets you push and pull draft changesets between repositories along with their obsolescence markers. This opens up a number of interesting possibilities. +

+

+ The simplest scenario is a single developer working across two computers. Say you’re working on code that must be tested on a remote test server, probably in a rack somewhere, only accessible by SSH, and running an “enterprise-grade” (out-of-date) OS. But you probably prefer to write code locally: everything is setup the way you like it, and you can use your preferred editor, IDE, merge/diff tools, etc. +

+

+ Traditionally, your options are limited: either +

+
+
+
    +
  • (ab)use your source control system by committing half-working code in order to get it onto the remote test server, or +
  • +
  • go behind source control’s back by using rsync (or similar) to transfer your code back-and-forth until it is ready to commit +
  • +
+
+
+

+ The former is less bad with distributed version control systems like Mercurial, but it’s still far from ideal. (One important version control “best practice” is that every commit should make things just a little bit better, i.e. you should never commit code that is worse than what came before.) The latter, avoiding version control entirely, means that you’re walking a tightrope without a safety net. One accidental rsync in the wrong direction could destroy hours of work. +

+

+ Using Mercurial with evolve to share mutable history solves these problems. As with single-repository evolve, you can commit whenever the code is demonstrably better, even if all the tests aren’t passing yet—just hg amend when they are. And you can transfer those half-baked changesets between repositories to try things out on your test server before anything is carved in stone. +

+

+ A less common scenario is multiple developers sharing mutable history, typically for code review. We’ll cover this scenario later. First, we will cover single-user sharing. +

+
+

+ Sharing with a single developer +

+
+

+ Publishing and non-publishing repositories +

+

+ The key to shared mutable history is to keep your changesets in draft phase as you pass them around. Recall that by default, hg push promotes changesets from draft to public, and public changesets are immutable. You can change this behaviour by reconfiguring the remote repository so that it is non-publishing. (Short version: set phases.publish to false. Long version follows.) +

+
+
+

+ Setting up +

+

+ We’ll work through an example with three local repositories, although in the real world they’d most likely be on three different computers. First, the public repository is where tested, polished changesets live, and it is where you synchronize with the rest of your team. +

+
+
+
$ hg init public
+
+
+
+

+ We’ll need two clones where work gets done, test-repo and dev-repo: +

+
+
+
$ hg clone public test-repo
+updating to branch default
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ hg clone test-repo dev-repo
+updating to branch default
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+
+

+ dev-repo is your local machine, with GUI merge tools and IDEs and everything configured just the way you like it. test-repo is the test server in a rack somewhere behind SSH. So for the most part, we’ll develop in dev-repo, push to test-repo, test and polish there, and push to public. +

+

+ The key to shared mutable history is to make the target repository, in this case test-repo, non-publishing. And, of course, we have to enable the evolve extension in both test-repo and dev-repo. +

+

+ First, edit the configuration for test-repo: +

+
+
+
$ hg -R test-repo config --edit --local
+
+
+
+

+ and add +

+
+
+
[phases]
+publish = false
+
+[extensions]
+evolve =
+
+
+
+

+ Then edit the configuration for dev-repo: +

+
+
+
$ hg -R dev-repo config --edit --local
+
+
+
+

+ and add +

+
+
+
[extensions]
+evolve =
+
+
+
+

+ Keep in mind that in real life, these repositories would probably be on separate computers, so you’d have to login to each one to configure each repository. +

+

+ To start things off, let’s make one public, immutable changeset: +

+
+
+
$ cd test-repo
+$ echo 'my new project' > file1
+$ hg add file1
+$ hg commit -m 'create new project'
+$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files
+
+
+
+

+ and pull that into the development repository: +

+
+
+
$ cd ../dev-repo
+$ hg pull -u
+[...]
+added 1 changesets with 1 changes to 1 files
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+
+
+
+

+ Example 1: Amend a shared changeset +

+

+ Everything you learned in the user guide applies to work done in dev-repo. You can commit, amend, uncommit, evolve, and so forth just as before. +

+

+ Things get different when you push changesets to test-repo. Or rather, things stay the same, which is different: because we configured test-repo to be non-publishing, draft changesets stay draft when we push them to test-repo. Importantly, they’re also draft (mutable) in test-repo. +

+

+ Let’s commit a preliminary change and push it to test-repo for testing. +

+
+
+
$ echo 'fix fix fix' > file1
+$ hg commit -m 'prelim change'
+$ hg push ../test-repo
+
+
+
+

+ At this point, dev-repo and test-repo have the same changesets in the same phases: +

+
+
+ [figure SG01: rev 0:0dc9 public, rev 1:f649 draft, same on both repos] +
+
+

+ (You may notice a change in notation from the user guide: now changesets are labelled with their revision number and the first four digits of the 40-digit hexadecimal changeset ID. Mercurial revision numbers are never stable when working across repositories, especially when obsolescence is involved. We’ll see why shortly.) +

+

+ Now let’s switch to test-repo to test our change: +

+
+
+
$ cd ../test-repo
+$ hg update
+
+
+
+

+ Don’t forget to hg update! Pushing only adds changesets to a remote repository; it does not update the working directory (unless you have a hook that updates for you). +

+

+ Now let’s imagine the tests failed because we didn’t use proper punctuation and capitalization (oops). Let’s amend our preliminary fix (and fix the lame commit message while we’re at it): +

+
+
+
$ echo 'Fix fix fix.' > file1
+$ hg amend -m 'fix bug 37'
+
+
+
+

+ Now we’re in a funny intermediate state (figure 2): revision 1:f649 is obsolete in test-repo, having been replaced by revision 3:60ff (revision 2:2a03 is another one of those temporary amend commits that we saw in the user guide)—but dev-repo knows nothing of these recent developments. +

+
+
+ [figure SG02: test-repo has rev 0:0dc9 public, rev 1:f649, 2:2a03 obsolete, rev 3:60ff draft; dev-repo same as in SG01] +
+
+

+ Let’s resynchronize: +

+
+
+
$ cd ../dev-repo
+$ hg pull -u
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+
+

+ As seen in figure 3, this transfers the new changeset and the obsolescence marker for revision 1. However, it does not transfer the temporary amend commit, because it is hidden. Push and pull transfer obsolescence markers between repositories, but they do not transfer hidden changesets. +

+
+
+ [figure SG03: dev-repo grows new rev 2:60ff, marks 1:f649 obsolete] +
+
+

+ Because of this deliberately incomplete synchronization, revision numbers in test-repo and dev-repo are no longer consistent. We must use changeset IDs. +

+
+
+

+ Example 2: Amend again, locally +

+

+ This process can repeat. Perhaps you figure out a more elegant fix to the bug, and want to mutate history so nobody ever knows you had a less-than-perfect idea. We’ll implement it locally in dev-repo and push to test-repo: +

+
+
+
$ echo 'Fix, fix, and fix.' > file1
+$ hg amend
+$ hg push
+
+
+
+

+ This time around, the temporary amend commit is in dev-repo, and it is not transferred to test-repo—the same as before, just in the opposite direction. Figure 4 shows the two repositories after amending in dev-repo and pushing to test-repo. +

+
+
+ [figure SG04: each repo has one temporary amend commit, but they’re different in each one] +
+
+

+ Let’s hop over to test-repo to test the more elegant fix: +

+
+
+
$ cd ../test-repo
+$ hg update
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+
+

+ This time, all the tests pass, so no further amending is required. This bug fix is finished, so we push it to the public repository: +

+
+
+
$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files
+
+
+
+

+ Note that only one changeset—the final version, after two amendments—was actually pushed. Again, Mercurial doesn’t transfer hidden changesets on push and pull. +

+

+ So the picture in public is much simpler than in either dev-repo or test-repo. Neither of our missteps nor our amendments are publicly visible, just the final, beautifully polished changeset: +

+
+
+ [figure SG05: public repo with rev 0:0dc9, 1:de61, both public] +
+
+

+ There is one important step left to do. Because we pushed from test-repo to public, the pushed changeset is in public phase in those two repositories. But dev-repo has been out-of-the-loop; changeset de61 is still draft there. If we’re not careful, we might mutate history in dev-repo, obsoleting a changeset that is already public. Let’s avoid that situation for now by pushing up to dev-repo: +

+
+
+
$ hg push ../dev-repo
+pushing to ../dev-repo
+searching for changes
+no changes found
+
+
+
+

+ Even though no changesets were pushed, Mercurial still pushed obsolescence markers and phase changes to dev-repo. +

+

+ A final note: since this fix is now public, it is immutable. It’s no longer possible to amend it: +

+
+
+
$ hg amend -m 'fix bug 37'
+abort: cannot amend public changesets
+
+
+
+

+ This is, after all, the whole point of Mercurial’s phases: to prevent rewriting history that has already been published. +

+
+
+
+

+ Sharing with multiple developers: code review +

+

+ Now that you know how to share your own mutable history across multiple computers, you might be wondering if it makes sense to share mutable history with others. It does, but you have to be careful, stay alert, and communicate with your peers. +

+

+ Code review is a good use case for sharing mutable history across multiple developers: Alice commits a draft changeset, submits it for review, and amends her changeset until her reviewer is satisfied. Meanwhile, Bob is also committing draft changesets for review, amending until his reviewer is satisfied. Once a particular changeset passes review, the respective author (Alice or Bob) pushes it to the public (publishing) repository. +

+

+ Incidentally, the reviewers here can be anyone: maybe Bob and Alice review each other’s work; maybe the same third party reviews both; or maybe they pick different experts to review their work on different parts of a large codebase. Similarly, it doesn’t matter if reviews are conducted in person, by email, or by carrier pigeon. Code review is outside of the scope of Mercurial, so all we’re looking at here is the mechanics of committing, amending, pushing, and pulling. +

+
+

+ Setting up +

+

+ To demonstrate, let’s start with the public repository as we left it in the last example, with two immutable changesets (figure 5 above). We’ll clone a review repository from it, and then Alice and Bob will both clone from review. +

+
+
+
$ hg clone public review
+updating to branch default
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ hg clone review alice
+updating to branch default
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ hg clone review bob
+updating to branch default
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+
+

+ We need to configure Alice’s and Bob’s working repositories to enable evolve. First, edit Alice’s configuration with +

+
+
+
$ hg -R alice config --edit --local
+
+
+
+

+ and add +

+
+
+
[extensions]
+evolve =
+
+
+
+

+ Then edit Bob’s repository configuration: +

+
+
+
$ hg -R bob config --edit --local
+
+
+
+

+ and add the same text. +

+
+
+

+ Example 3: Alice commits and amends a draft fix +

+

+ We’ll follow Alice working on a bug fix. We’re going to use bookmarks to make it easier to understand multiple branch heads in the review repository, so Alice starts off by creating a bookmark and committing her first attempt at a fix: +

+
+
+
$ hg bookmark bug15
+$ echo 'fix' > file2
+$ hg commit -A -u alice -m 'fix bug 15 (v1)'
+adding file2
+
+
+
+

+ Note the unorthodox “(v1)” in the commit message. We’re just using that to make this tutorial easier to follow; it’s not something we’d recommend in real life. +

+

+ Of course Alice wouldn’t commit unless her fix worked to her satisfaction, so it must be time to solicit a code review. She does this by pushing to the review repository: +

+
+
+
$ hg push -B bug15
+[...]
+added 1 changesets with 1 changes to 1 files
+exporting bookmark bug15
+
+
+
+

+ (The use of -B is important to ensure that we only push the bookmarked head, and that the bookmark itself is pushed. See this guide to bookmarks, especially the Sharing Bookmarks section, if you’re not familiar with bookmarks.) +

+

+ Some time passes, and Alice receives her code review. As a result, Alice revises her fix and submits it for a second review: +

+
+
+
$ echo 'Fix.' > file2
+$ hg amend -m 'fix bug 15 (v2)'
+$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+updating bookmark bug15
+
+
+
+

+ Figure 6 shows the state of the review repository at this point. +

+
+
+ [figure SG06: rev 2:fn1e is Alice’s obsolete v1, rev 3:cbdf is her v2; both children of rev 1:de61] +
+
+

+ After a busy morning of bug fixing, Alice stops for lunch. Let’s see what Bob has been up to. +

+
+
+

+ Example 4: Bob implements and publishes a new feature +

+

+ Meanwhile, Bob has been working on a new feature. Like Alice, he’ll use a bookmark to track his work, and he’ll push that bookmark to the review repository, so that reviewers know which changesets to review. +

+
+
+
$ cd ../bob
+$ echo 'stuff' > file1
+$ hg bookmark featureX
+$ hg commit -u bob -m 'implement feature X (v1)'          # rev 4:1636
+$ hg push -B featureX
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+exporting bookmark featureX
+
+
+
+

+ When Bob receives his code review, he improves his implementation a bit, amends, and submits the resulting changeset for review: +

+
+
+
$ echo 'do stuff' > file1
+$ hg amend -m 'implement feature X (v2)'                  # rev 5:0eb7
+$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+updating bookmark featureX
+
+
+
+

+ Unfortunately, that still doesn’t pass muster. Bob’s reviewer insists on proper capitalization and punctuation. +

+
+
+
$ echo 'Do stuff.' > file1
+$ hg amend -m 'implement feature X (v3)'                  # rev 6:540b
+
+
+
+

+ On the bright side, the second review said, “Go ahead and publish once you fix that.” So Bob immediately publishes his third attempt: +

+
+
+
$ hg push ../public
+[...]
+added 1 changesets with 1 changes to 1 files
+
+
+
+

+ It’s not enough just to update public, though! Other people also use the review repository, and right now it doesn’t have Bob’s latest amendment (“v3”, revision 6:540b), nor does it know that the precursor of that changeset (“v2”, revision 5:0eb7) is obsolete. Thus, Bob pushes to review as well: +

+
+
+
$ hg push ../review
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+updating bookmark featureX
+
+
+
+

+ Figure 7 shows the result of Bob’s work in both review and public. +

+
+
+ [figure SG07: review includes Alice’s draft work on bug 15, as well as Bob’s v1, v2, and v3 changes for feature X: v1 and v2 obsolete, v3 public. public contains only the final, public implementation of feature X] +
+
+

+ Incidentally, it’s important that Bob push to public before review. If he pushed to review first, then revision 6:540b would still be in draft phase in review, but it would be public in both Bob’s local repository and the public repository. That could lead to confusion at some point, which is easily avoided by pushing first to public. +

+
+
+

+ Example 5: Alice integrates and publishes +

+

+ Finally, Alice gets back from lunch and sees that the carrier pigeon with her second review has arrived (or maybe it’s in her email inbox). Alice’s reviewer approved her amended changeset, so she pushes it to public: +

+
+
+
$ hg push ../public
+[...]
+remote has heads on branch 'default' that are not known locally: 540ba8f317e6
+abort: push creates new remote head cbdfbd5a5db2!
+(pull and merge or see "hg help push" for details about pushing new heads)
+
+
+
+

+ Oops! Bob has won the race to push first to public. So Alice needs to integrate with Bob: let’s pull his changeset(s) and see what the branch heads are. +

+
+
+
$ hg pull ../public
+[...]
+added 1 changesets with 1 changes to 1 files (+1 heads)
+(run 'hg heads' to see heads, 'hg merge' to merge)
+$ hg log -G -q -r 'head()' --template '{rev}:{node|short}  ({author})\n'
+o  5:540ba8f317e6  (bob)
+|
+| @  4:cbdfbd5a5db2  (alice)
+|/
+
+
+
+

+ We’ll assume Alice and Bob are perfectly comfortable with rebasing changesets. (After all, they’re already using mutable history in the form of amend.) So Alice rebases her changeset on top of Bob’s and publishes the result: +

+
+
+
$ hg rebase -d 5
+$ hg push ../public
+[...]
+added 1 changesets with 1 changes to 1 files
+$ hg push ../review
+[...]
+added 1 changesets with 0 changes to 0 files
+updating bookmark bug15
+
+
+
+

+ The result, in both review and public repositories, is shown in figure 8. +

+
+
+ [figure SG08: review shows v1 and v2 of Alice’s fix, then v1, v2, v3 of Bob’s feature, finally Alice’s fix rebased onto Bob’s. public just shows the final public version of each changeset] +
+
+
+
+
+

+ Getting into trouble with shared mutable history +

+

+ Mercurial with evolve is a powerful tool, and using powerful tools can have consequences. (You can cut yourself badly with a sharp knife, but every competent chef keeps several around. Ever try to chop onions with a spoon?) +

+

+ In the user guide, we saw examples of unstbale changesets, which are the most common type of troubled changeset. (Recall that a non-obsolete changeset with obsolete ancestors is an orphan.) +

+

+ Two other types of troubles can happen: divergent and bumped changesets. Both are more likely with shared mutable history, especially mutable history shared by multiple developers. +

+
+

+ Setting up +

+

+ For these examples, we’re going to use a slightly different workflow: as before, Alice and Bob share a public repository. But this time there is no review repository. Instead, Alice and Bob put on their cowboy hats, throw good practice to the wind, and pull directly from each other’s working repositories. +

+

+ So we throw away everything except public and reclone: +

+
+
+
$ rm -rf review alice bob
+$ hg clone public alice
+updating to branch default
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ hg clone public bob
+updating to branch default
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+
+
+

+ Once again we have to configure their repositories: enable evolve and (since Alice and Bob will be pulling directly from each other) make their repositories non-publishing. Edit Alice’s configuration: +

+
+
+
$ hg -R alice config --edit --local
+
+
+
+

+ and add +

+
+
+
[extensions]
+rebase =
+evolve =
+
+[phases]
+publish = false
+
+
+
+

+ Then edit Bob’s repository configuration: +

+
+
+
$ hg -R bob config --edit --local
+
+
+
+

+ and add the same text. +

+
+
+

+ Example 6: Divergent changesets +

+

+ When an obsolete changeset has two successors, those successors are divergent. One way to get into such a situation is by failing to communicate with your teammates. Let’s see how that might happen. +

+

+ First, we’ll have Bob commit a bug fix that could still be improved: +

+
+
+
$ cd bob
+$ echo 'pretty good fix' >> file1
+$ hg commit -u bob -m 'fix bug 24 (v1)'                   # rev 4:2fe6
+
+
+
+

+ Since Alice and Bob are now in cowboy mode, Alice pulls Bob’s draft changeset and amends it herself. +

+
+
+
$ cd ../alice
+$ hg pull -u ../bob
+[...]
+added 1 changesets with 1 changes to 1 files
+$ echo 'better fix (alice)' >> file1
+$ hg amend -u alice -m 'fix bug 24 (v2 by alice)'
+
+
+
+

+ But Bob has no idea that Alice just did this. (See how important good communication is?) So he implements a better fix of his own: +

+
+
+
$ cd ../bob
+$ echo 'better fix (bob)' >> file1
+$ hg amend -u bob -m 'fix bug 24 (v2 by bob)'             # rev 6:a360
+
+
+
+

+ At this point, the divergence exists, but only in theory: Bob’s original changeset, 4:2fe6, is obsolete and has two successors. But those successors are in different repositories, so the trouble is not visible to anyone yet. It will be as soon as Bob pulls from Alice’s repository (or vice-versa). +

+
+
+
$ hg pull ../alice
+[...]
+added 1 changesets with 1 changes to 2 files (+1 heads)
+(run 'hg heads' to see heads, 'hg merge' to merge)
+2 new divergent changesets
+
+
+
+

+ Figure 9 shows the situation in Bob’s repository. +

+
+
+ [figure SG09: Bob’s repo with 2 heads for the 2 divergent changesets, 6:a360 and 7:e3f9; wc is at 6:a360; both are successors of obsolete 4:2fe6, hence divergence] +
+
+

+ Now we need to get out of trouble. As usual, the answer is to evolve history. +

+
+
+
$ HGMERGE=internal:other hg evolve
+merge:[6] fix bug 24 (v2 by bob)
+with: [7] fix bug 24 (v2 by alice)
+base: [4] fix bug 24 (v1)
+0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+
+
+
+

+ Figure 10 shows how Bob’s repository looks now. +

+
+
+ [figure SG10: only one visible head, 9:5ad6, successor to hidden 6:a360 and 7:e3f9] +
+
+

+ We carefully dodged a merge conflict by specifying a merge tool (internal:other) that will take Alice’s changes over Bob’s. (You might wonder why Bob wouldn’t prefer his own changes by using internal:local. He’s avoiding a bug in evolve that occurs when evolving divergent changesets using internal:local.) +

+

+ # XXX this link does not work .. bug: https://bitbucket.org/marmoute/mutable-history/issue/48/ +

+

+ ** STOP HERE: WORK IN PROGRESS ** +

+
+
+

+ Phase-divergence: when a rewritten changeset is made public +

+

+ If Alice and Bob are collaborating on some mutable changesets, it’s possible to get into a situation where an otherwise worthwhile changeset cannot be pushed to the public repository; it is phase-divergent with another changeset that was made public first. Let’s demonstrate one way this could happen. +

+

+ It starts with Alice committing a bug fix. Right now, we don’t yet know if this bug fix is good enough to push to the public repository, but it’s good enough for Alice to commit. +

+
+
+
$ cd alice
+$ echo 'fix' > file2
+$ hg commit -A -m 'fix bug 15'
+adding file2
+
+
+
+

+ Now Bob has a bad idea: he decides to pull whatever Alice is working on and tweak her bug fix to his taste: +

+
+
+
$ cd ../bob
+$ hg pull -u ../alice
+[...]
+added 1 changesets with 1 changes to 1 files
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ echo 'Fix.' > file2
+$ hg amend -A -m 'fix bug 15 (amended)'
+
+
+
+

+ (Note the lack of communication between Alice and Bob. Failing to communicate with your colleagues is a good way to get into trouble. Nevertheless, evolve can usually sort things out, as we will see.) +

+
+
+ [figure SG06: Bob’s repo with one amendment] +
+
+

+ After some testing, Alice realizes her bug fix is just fine as it is: no need for further polishing and amending, this changeset is ready to publish. +

+
+
+
$ cd ../alice
+$ hg push
+[...]
+added 1 changesets with 1 changes to 1 files
+
+
+
+

+ This introduces a contradiction: in Bob’s repository, changeset 2:e011 (his copy of Alice’s fix) is obsolete, since Bob amended it. But in Alice’s repository (and the public repository), that changeset is public: it is immutable, carved in stone for all eternity. No changeset can be both obsolete and public, so Bob is in for a surprise the next time he pulls from public: +

+
+
+
$ cd ../bob
+$ hg pull -q -u
+1 new phase-divergent changesets
+
+
+
+

+ Figure 7 shows what just happened to Bob’s repository: changeset 2:e011 is now public, so it can’t be obsolete. When that changeset was obsolete, it made perfect sense for it to have a successor, namely Bob’s amendment of Alice’s fix (changeset 4:fe88). But it’s illogical for a public changeset to have a successor, so 4:fe88 is troubled: it has become bumped. +

+
+
+ [figure SG07: 2:e011 now public not obsolete, 4:fe88 now bumped] +
+
+

+ As usual when there’s trouble in your repository, the solution is to evolve it: +

+
+
+
$ hg evolve --all
+
+
+
+

+ Figure 8 illustrates Bob’s repository after evolving away the bumped changeset. Ignoring the obsolete changesets, Bob now has a nice, clean, simple history. His amendment of Alice’s bug fix lives on, as changeset 5:227d—albeit with a software-generated commit message. (Bob should probably amend that changeset to improve the commit message.) But the important thing is that his repository no longer has any troubled changesets, thanks to evolve. +

+
+
+ [figure SG08: 5:227d is new, formerly bumped changeset 4:fe88 now hidden] +
+
+
+
+
+

+ Conclusion +

+

+ Mutable history is a powerful tool. Like a sharp knife, an experienced user can do wonderful things with it, much more wonderful than with a dull knife (never mind a rusty spoon). At the same time, an inattentive or careless user can do harm to himself or others. Mercurial with evolve goes to great lengths to limit the harm you can do by trying to handle all possible types of “troubled” changesets. Nevertheless, having a first-aid kit nearby does not mean you should stop being careful with sharp knives. +

+

+ Mutable history shared across multiple repositories by a single developer is a natural extension of this model. Once you are used to using a single sharp knife on its own, it’s pretty straightforward to chop onions and mushrooms using the same knife, or to alternate between two chopping boards with different knives. +

+

+ Mutable history shared by multiple developers is a scary place to go. Imagine a professional kitchen full of expert chefs tossing their favourite knives back and forth, with the occasional axe or chainsaw thrown in to spice things up. If you’re confident that you and your colleagues can do it without losing a limb, go for it. But be sure to practice a lot first before you rely on it! +

+
+
+
+
+

+ «  Evolve: User Guide   ::   Contents   ::   Evolve: Concepts  » +

+
+ + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected-metadata.json new file mode 100644 index 000000000..ed10c3040 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Creator Name", + "Direction": null, + "Excerpt": "Preferred description", + "Image": null, + "Title": "My title", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected.html new file mode 100644 index 000000000..b282bddee --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/expected.html @@ -0,0 +1,19 @@ +
+

Test document title

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/source.html new file mode 100644 index 000000000..1e5c1ad7b --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/metadata-content-missing/source.html @@ -0,0 +1,33 @@ + + + + + Title Element + + + + + + + +
+

Test document title

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected-metadata.json new file mode 100644 index 000000000..59c9941eb --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": "Lorem\n ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\n\ttab here\n incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\n quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\n cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\n proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + "Image": null, + "Title": "Normalize space test", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected.html new file mode 100644 index 000000000..18739c3f9 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/expected.html @@ -0,0 +1,26 @@ +
+

Lorem

+

+ Lorem + ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tab here + incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

Foo

+

+ Tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation + + + + + ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/source.html new file mode 100644 index 000000000..b23079824 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/normalize-spaces/source.html @@ -0,0 +1,35 @@ + + + + + Normalize space test + + +
+

Lorem

+
+ Lorem + ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tab here + incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +
+

Foo

+
+ Tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation + + + + + ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +
+
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected-images.json new file mode 100644 index 000000000..93da552c4 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected-images.json @@ -0,0 +1,11 @@ +[ + "https:\/\/static01.nyt.com\/images\/2019\/02\/21\/nyregion\/21winterutilities1\/00winterutilities1-facebookJumbo.jpg", + "https:\/\/static01.nyt.com\/images\/2019\/02\/21\/nyregion\/21winterutilities1\/merlin_150498339_cf9085e5-9756-4169-a5a5-5b516316a3fa-articleLarge.jpg?quality=75&auto=webp&disable=upscale", + "https:\/\/static01.nyt.com\/images\/2018\/02\/20\/multimedia\/author-corey-kilgannon\/author-corey-kilgannon-thumbLarge.jpg", + "https:\/\/static01.nyt.com\/images\/2019\/02\/21\/nyregion\/21winterutilitiesOAK15\/merlin_56025490_f9412a36-eeb9-4a10-a41e-f324eb7a3248-articleLarge.jpg?quality=75&auto=webp&disable=upscale", + "https:\/\/static01.nyt.com\/images\/2019\/02\/15\/nyregion\/00winterutilitiesOAK11\/merlin_94083158_9e622a52-ec2f-4fbd-845c-5d530e94bc82-articleLarge.jpg?quality=90&auto=webp", + "https:\/\/static01.nyt.com\/images\/2019\/02\/21\/nyregion\/21winterutilitiesOAK13\/merlin_77720485_1f5be529-e659-49c3-a0bc-a3f312835d14-articleLarge.jpg?quality=90&auto=webp", + "https:\/\/static01.nyt.com\/images\/2017\/12\/07\/nyregion\/00winter4\/00winter4-articleLarge.jpg?quality=90&auto=webp", + "https:\/\/static01.nyt.com\/images\/2019\/02\/15\/nyregion\/00winterutilitiesOAK12\/merlin_77751796_7f1b7a7a-23e9-49b2-b12e-1edfed680911-articleLarge.jpg?quality=90&auto=webp", + "https:\/\/static01.nyt.com\/images\/2019\/02\/12\/nyregion\/00winterutilities2\/merlin_150504129_e893b874-01eb-4d8f-8158-18512153e414-articleLarge.jpg?quality=90&auto=webp" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected-metadata.json new file mode 100644 index 000000000..3d9b539ce --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "By Corey Kilgannon", + "Direction": null, + "Excerpt": "New York\u2019s aging below-street infrastructure is tough to maintain, and the corrosive rock salt and \u201cfreeze-thaw\u201d cycles of winter make it even worse.", + "Image": "https:\/\/static01.nyt.com\/images\/2019\/02\/21\/nyregion\/21winterutilities1\/00winterutilities1-facebookJumbo.jpg", + "Title": "Manhole Fires and Burst Pipes: How Winter Wreaks Havoc on What\u2019s Underneath N.Y.C.", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected.html new file mode 100644 index 000000000..a8a9bc341 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/expected.html @@ -0,0 +1,267 @@ +
+ +
+ + +

+ New York’s aging below-street infrastructure is tough to maintain, and the corrosive rock salt and “freeze-thaw” cycles of winter make it even worse. +

+
+
+

Image +

+
+ A Con Edison worker repairing underground cables this month in Flushing, Queens. The likely source of the problem was water and rock salt that had seeped underground.CreditCreditChang W. Lee/The New York Times +
+
+
+
+
+

Corey Kilgannon +

+ +
+
    +
  • + +
  • +
  • + +
  • +
+
+
+
+
+

+ [What you need to know to start the day: Get New York Today in your inbox.] +

+

+ A series of recent manhole fires in the heart of Manhattan forced the evacuation of several theaters and was a stark reminder that the subway is not the only creaky infrastructure beneath the streets of New York City. +

+

+ Underground lies a chaotic assemblage of utilities that, much like the subway, are lifelines for the city: a sprawling tangle of water mains, power cables, gas and steam lines, telecom wires and sewers. +

+

+ The city has one of the oldest and largest networks of subterranean infrastructure in the world, with some portions dating more than a century and prone to leaks and cracks. +

+

+ And winter — from the corrosive rock salt used on streets and sidewalks to “freeze-thaw” cycles that weaken pipes — makes infrastructure problems even worse. +

+
+
+

+ In the late 1800s, many of the city’s overhead utilities were buried to lessen the exposure to winter weather. “People think it’s all protected and safe, but it’s really not,” said Patrick McHugh, vice president of electrical engineering and planning for Con Edison, which maintains about 90,000 miles of underground cable in the city. +

+

+ “You have water, sewage, electricity and gas down there, and people don’t appreciate the effort that goes into keeping all that working,” he added. +

+
+
+
+

Image +

+
+ In the late 1800s, overhead utilities were buried to lessen the exposure to winter weather.CreditKirsten Luce for The New York Times +
+
+
+
+ +

+ When rock salt melts ice, and the water seeps down manholes and into electrical units, it can set off fires and explosions strong enough to pop a 300-pound manhole cover five stories into the air. +

+

+ For days after a storm, Con Edison officials say, they often deal with scores of electrical fires caused by the rock salt eating away at electrical cable insulation. The wet salt can create sparking that burns the insulation, producing both fire and gases that can combust and pop the manhole lids. +

+

+ To alleviate the threat, the officials said, the utility switched most of its manhole covers to vented ones that allow gases to escape, “so they cannot form a combustible amount,” Mr. McHugh said. +

+
+
+

+ “It also lets smoke escape, which can tip off the public to notify the authorities,” he added. +

+

+ Winter can also bring an increase in gas-line breakages. Con Edison, which maintains 4,300 miles of gas mains in and around New York City, records about 500 leaks — most of them nonemergencies — in a typical month, but many more in winter. +

+

+ Even this past January, which was unseasonably mild, there were 750 leaks, Con Edison officials said. +

+
+
+
+
+

Image

+
+
+ There are typically between 400 and 600 water main breaks each year in New York City, an official said.CreditMichael Appleton for The New York Times +
+
+
+
+ +

+ The extreme temperature swings that many researchers link to climate change are adding to the challenges of winter. +

+

+ Officials monitor weather forecasts closely for freeze-thaw cycles, when they put extra repair crews on call. +

+

+ During a polar vortex in late January, for instance, single-digit temperatures in the city quickly ballooned into the 50s. The thaw, much welcomed by many New Yorkers, worried Tasos Georgelis, deputy commissioner for water and sewer operations at the Department of Environmental Protection, which operates the city’s water system. +

+

+ “When you get a freeze and a thaw, the ground around the water mains expands and contracts, and puts external pressure on the pipes,” Mr. Georgelis said. +

+

+ Along the city’s roughly 6,500 miles of water mains, there are typically between 400 and 600 breaks a year, he added. The majority occur in winter, when the cold can make older cast-iron mains brittle. +

+
+
+

+ Environmental Protection officials said the department repaired 75 water-main breaks in January, including one in Lower Manhattan that disrupted rush-hour subway service and another on the West Side that snarled traffic and left nearby buildings without water for hours. +

+

+ The city’s 7,500 miles of sewer lines are less affected by cold weather because they are generally buried deeper than other utilities, below the frost line, agency officials said. +

+
+
+
+
+

Image

+
+
+ In 1978, a water main break caused severe flooding in Bushwick, Brooklyn.CreditFred R. Conrad/The New York Times +
+
+
+
+ +

+ Upgrading the city’s below-street utilities is a slow, painstaking process, “because you have such a fixed-in-place system,” said Rae Zimmerman, a research professor of planning and public administration at New York University. +

+

+ But there is progress. Con Edison officials said they had begun replacing the city’s nearly 1,600 miles of natural gas lines — which were made of either cast iron or unprotected steel — with plastic piping. The plastic is less susceptible to corrosion, cracks and leaks, said the officials, who added that they were swapping about 100 miles of line each year. +

+

+ The city is also replacing older, leak-prone water and sewer mains. +

+

+ Some pipes that are more than a century old hold up because they were built with a thicker grade of cast iron, according to Environmental Protection Department officials. For less healthy ones, the agency has invested more than $1 billion in the past five years — with an additional $1.4 billion budgeted over the next five years — for upgrades and replacements. New pipes will be made of a more durable, graphite-rich cast iron known as ductile iron. +

+
+
+
+
+

Image

+
+
+ Matt Cruz snowboarded through Manhattan’s Lower East Side after a snowstorm in 2016 left the streets coated in slush and rock salt.CreditHiroko Masuike/The New York Times +
+
+
+
+ +

+ Of course, winter also poses problems aboveground. Most nonemergency repair and construction work involving concrete is halted because concrete and some types of dirt, used to fill in trenches, freeze in colder temperatures, said Ian Michaels, a spokesman for the city’s Department of Design and Construction. +

+

+ Digging by hand is also a challenge in frozen ground, so many excavations that are close to pipes and other utilities are put off, Mr. Michaels said. +

+
+
+

+ And asphalt is harder to obtain because it must be kept and transported at high temperatures, he added. +

+

+ In the extreme cold, city officials will not risk shutting down water mains for construction because spillage into the street could freeze, Mr. Michaels said. He added that stopping the water flow could freeze the private water-service connections that branch off the mains, he said. +

+

+ Even the basic task of locating utilities under the street can be complicated because infrastructure has been added piecemeal over the decades. +

+
+
+
+
+

Image

+
+
+ A water main break in Manhattan in 2014. “When you get a freeze and a thaw, the ground around the water mains expands and contracts, and puts external pressure on the pipes,” said Tasos Georgelis of the city's Department of Environmental Protection.CreditÃngel Franco/The New York Times +
+
+
+
+ +

+ Street surfaces are affected by winter weather, too: Last year, the city filled 255,904 potholes. +

+

+ And should anyone forget that filling potholes, like snow removal, is a sacred staple of constituent services, transportation officials have compiled the number of potholes the city has filled — more than 1,786,300 — since Mayor Bill de Blasio took office in 2014. +

+

+ Potholes form when water and salt seep into cracks, freeze and expand, creating a larger crevice, said Joe Carbone, who works for the Transportation Department, where he is known as the pothole chief. +

+

+ Simply put, more freeze-thaw cycles result in more potholes, he said. Currently, the department has 25 crews repairing potholes. During peak pothole-repair season in early March, that number can expand to more than 60. +

+
+
+

+ Still, the department is continually resurfacing the city’s more than 6,000 miles of streets and 19,000 lane miles. Each year, agency officials said, it uses more than one million tons of asphalt to repave more than 1,300 lane-miles of street. +

+ +
+
+
+
+

Image

+
+
+ Workers learning how to fix water main breaks at a training center in Queens.CreditChang W. Lee/The New York Times +
+
+
+
+ +

+ Of the 400 city laborers who work on water mains, many learn the finer points of leak repair at a training center in Queens, where underground pipes are made to spring leaks for repair drills. +

+

+ Workers from the Department of Environmental Protection recently gathered around a muddy hole as a co-worker, Nehemiah Dejesus, scrambled to apply a stainless-steel repair clamp around a cracked segment that was spewing water. +

+

+ “Don’t get nervous,” instructed Milton Velez, the agency’s district supervisor for Queens. +

+

+ “I’m not,” Mr. Dejesus said as he secured the clamp and stopped the leak. “It’s ‘Showtime at the Apollo.’” +

+
+ + +
+
+ +
+

+ Corey Kilgannon is a Metro reporter covering news and human interest stories. His writes the Character Study column in the Sunday Metropolitan section. He was also part of the team that won the 2009 Pulitzer Prize for Breaking News. @coreykilgannon Facebook +

+
+

+ A version of this article appears in print on

, on Page

A

22

of the New York edition

with the headline:

Under the City’s Streets, A Battle Against Winter. Order Reprints | Today’s Paper | Subscribe +

+ +
+ +
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/source.html new file mode 100644 index 000000000..293657692 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-3/source.html @@ -0,0 +1,1638 @@ + + + + + + Manhole Fires and Burst Pipes: How Winter Wreaks Havoc on What’s Underneath N.Y.C. - The New York Times + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+
+
+
+
+
+ +
+
+ +
Skip to contentSkip to site index +
+
+ New York +
+
+ + +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + +
+
+
+
+
+ +
+

+ Manhole Fires and Burst Pipes: How Winter Wreaks Havoc on What’s Underneath N.Y.C. +

+
+

+ New York’s aging below-street infrastructure is tough to maintain, and the corrosive rock salt and “freeze-thaw” cycles of winter make it even worse. +

+
+
+
+
+
+ Image +
+
+ A Con Edison worker repairing underground cables this month in Flushing, Queens. The likely source of the problem was water and rock salt that had seeped underground.CreditCreditChang W. Lee/The New York Times +
+
+
+
+
+
+
+
+ Corey Kilgannon +
+
+

+ By Corey Kilgannon +

+
+
+
    +
  • + +
  • +
  • +
    + +
    +
  • +
+
+
+
+
+
+
+

+ [What you need to know to start the day: Get New York Today in your inbox.] +

+

+ A series of recent manhole fires in the heart of Manhattan forced the evacuation of several theaters and was a stark reminder that the subway is not the only creaky infrastructure beneath the streets of New York City. +

+

+ Underground lies a chaotic assemblage of utilities that, much like the subway, are lifelines for the city: a sprawling tangle of water mains, power cables, gas and steam lines, telecom wires and sewers. +

+

+ The city has one of the oldest and largest networks of subterranean infrastructure in the world, with some portions dating more than a century and prone to leaks and cracks. +

+

+ And winter — from the corrosive rock salt used on streets and sidewalks to “freeze-thaw” cycles that weaken pipes — makes infrastructure problems even worse. +

+
+ +
+
+
+

+ In the late 1800s, many of the city’s overhead utilities were buried to lessen the exposure to winter weather. “People think it’s all protected and safe, but it’s really not,” said Patrick McHugh, vice president of electrical engineering and planning for Con Edison, which maintains about 90,000 miles of underground cable in the city. +

+

+ “You have water, sewage, electricity and gas down there, and people don’t appreciate the effort that goes into keeping all that working,” he added. +

+
+ +
+
+
+
+
+
+ Image +
+
+ In the late 1800s, overhead utilities were buried to lessen the exposure to winter weather.CreditKirsten Luce for The New York Times +
+
+
+
+
+
+ +

+ When rock salt melts ice, and the water seeps down manholes and into electrical units, it can set off fires and explosions strong enough to pop a 300-pound manhole cover five stories into the air. +

+

+ For days after a storm, Con Edison officials say, they often deal with scores of electrical fires caused by the rock salt eating away at electrical cable insulation. The wet salt can create sparking that burns the insulation, producing both fire and gases that can combust and pop the manhole lids. +

+

+ To alleviate the threat, the officials said, the utility switched most of its manhole covers to vented ones that allow gases to escape, “so they cannot form a combustible amount,” Mr. McHugh said. +

+
+ +
+
+
+

+ “It also lets smoke escape, which can tip off the public to notify the authorities,” he added. +

+

+ Winter can also bring an increase in gas-line breakages. Con Edison, which maintains 4,300 miles of gas mains in and around New York City, records about 500 leaks — most of them nonemergencies — in a typical month, but many more in winter. +

+

+ Even this past January, which was unseasonably mild, there were 750 leaks, Con Edison officials said. +

+
+ +
+
+
+
+
+
+ Image +
+
+
+
+
+ There are typically between 400 and 600 water main breaks each year in New York City, an official said.CreditMichael Appleton for The New York Times +
+
+
+
+
+
+ +

+ The extreme temperature swings that many researchers link to climate change are adding to the challenges of winter. +

+

+ Officials monitor weather forecasts closely for freeze-thaw cycles, when they put extra repair crews on call. +

+

+ During a polar vortex in late January, for instance, single-digit temperatures in the city quickly ballooned into the 50s. The thaw, much welcomed by many New Yorkers, worried Tasos Georgelis, deputy commissioner for water and sewer operations at the Department of Environmental Protection, which operates the city’s water system. +

+

+ “When you get a freeze and a thaw, the ground around the water mains expands and contracts, and puts external pressure on the pipes,” Mr. Georgelis said. +

+

+ Along the city’s roughly 6,500 miles of water mains, there are typically between 400 and 600 breaks a year, he added. The majority occur in winter, when the cold can make older cast-iron mains brittle. +

+
+ +
+
+
+

+ Environmental Protection officials said the department repaired 75 water-main breaks in January, including one in Lower Manhattan that disrupted rush-hour subway service and another on the West Side that snarled traffic and left nearby buildings without water for hours. +

+

+ The city’s 7,500 miles of sewer lines are less affected by cold weather because they are generally buried deeper than other utilities, below the frost line, agency officials said. +

+
+ +
+
+
+
+
+
+ Image +
+
+
+
+
+ In 1978, a water main break caused severe flooding in Bushwick, Brooklyn.CreditFred R. Conrad/The New York Times +
+
+
+
+
+
+ +

+ Upgrading the city’s below-street utilities is a slow, painstaking process, “because you have such a fixed-in-place system,” said Rae Zimmerman, a research professor of planning and public administration at New York University. +

+

+ But there is progress. Con Edison officials said they had begun replacing the city’s nearly 1,600 miles of natural gas lines — which were made of either cast iron or unprotected steel — with plastic piping. The plastic is less susceptible to corrosion, cracks and leaks, said the officials, who added that they were swapping about 100 miles of line each year. +

+

+ The city is also replacing older, leak-prone water and sewer mains. +

+

+ Some pipes that are more than a century old hold up because they were built with a thicker grade of cast iron, according to Environmental Protection Department officials. For less healthy ones, the agency has invested more than $1 billion in the past five years — with an additional $1.4 billion budgeted over the next five years — for upgrades and replacements. New pipes will be made of a more durable, graphite-rich cast iron known as ductile iron. +

+
+ +
+
+
+
+
+
+ Image +
+
+
+
+
+ Matt Cruz snowboarded through Manhattan’s Lower East Side after a snowstorm in 2016 left the streets coated in slush and rock salt.CreditHiroko Masuike/The New York Times +
+
+
+
+
+
+ +

+ Of course, winter also poses problems aboveground. Most nonemergency repair and construction work involving concrete is halted because concrete and some types of dirt, used to fill in trenches, freeze in colder temperatures, said Ian Michaels, a spokesman for the city’s Department of Design and Construction. +

+

+ Digging by hand is also a challenge in frozen ground, so many excavations that are close to pipes and other utilities are put off, Mr. Michaels said. +

+
+ +
+
+
+

+ And asphalt is harder to obtain because it must be kept and transported at high temperatures, he added. +

+

+ In the extreme cold, city officials will not risk shutting down water mains for construction because spillage into the street could freeze, Mr. Michaels said. He added that stopping the water flow could freeze the private water-service connections that branch off the mains, he said. +

+

+ Even the basic task of locating utilities under the street can be complicated because infrastructure has been added piecemeal over the decades. +

+
+ +
+
+
+
+
+
+ Image +
+
+
+
+
+ A water main break in Manhattan in 2014. “When you get a freeze and a thaw, the ground around the water mains expands and contracts, and puts external pressure on the pipes,” said Tasos Georgelis of the city's Department of Environmental Protection.CreditÃngel Franco/The New York Times +
+
+
+
+
+
+ +

+ Street surfaces are affected by winter weather, too: Last year, the city filled 255,904 potholes. +

+

+ And should anyone forget that filling potholes, like snow removal, is a sacred staple of constituent services, transportation officials have compiled the number of potholes the city has filled — more than 1,786,300 — since Mayor Bill de Blasio took office in 2014. +

+

+ Potholes form when water and salt seep into cracks, freeze and expand, creating a larger crevice, said Joe Carbone, who works for the Transportation Department, where he is known as the pothole chief. +

+

+ Simply put, more freeze-thaw cycles result in more potholes, he said. Currently, the department has 25 crews repairing potholes. During peak pothole-repair season in early March, that number can expand to more than 60. +

+
+ +
+
+
+

+ Still, the department is continually resurfacing the city’s more than 6,000 miles of streets and 19,000 lane miles. Each year, agency officials said, it uses more than one million tons of asphalt to repave more than 1,300 lane-miles of street. +

+
+ +
+
+
+
+
+
+ Image +
+
+
+
+
+ Workers learning how to fix water main breaks at a training center in Queens.CreditChang W. Lee/The New York Times +
+
+
+
+
+
+ +

+ Of the 400 city laborers who work on water mains, many learn the finer points of leak repair at a training center in Queens, where underground pipes are made to spring leaks for repair drills. +

+

+ Workers from the Department of Environmental Protection recently gathered around a muddy hole as a co-worker, Nehemiah Dejesus, scrambled to apply a stainless-steel repair clamp around a cracked segment that was spewing water. +

+

+ “Don’t get nervous,” instructed Milton Velez, the agency’s district supervisor for Queens. +

+

+ “I’m not,” Mr. Dejesus said as he secured the clamp and stopped the leak. “It’s ‘Showtime at the Apollo.’” +

+
+ +
+ +
+
+ +
+
+
+
+
+
+
+

+ Corey Kilgannon is a Metro reporter covering news and human interest stories. His writes the Character Study column in the Sunday Metropolitan section. He was also part of the team that won the 2009 Pulitzer Prize for Breaking News. @coreykilgannon Facebook +

+
+
+
+
+ A version of this article appears in print on , on Page A22 of the New York edition with the headline: Under the City’s Streets, A Battle Against Winter. Order Reprints | Today’s Paper | Subscribe +
+
+ +
+
+
+
+

+ Advertisement +

+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + +
+
+
+ + + + + + +
+ +
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected-images.json new file mode 100644 index 000000000..58b77887f --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected-images.json @@ -0,0 +1,4 @@ +[ + "https:\/\/static01.nyt.com\/images\/2018\/09\/15\/business\/15DEBTS01\/15DEBTS01-facebookJumbo.jpg", + "https:\/\/static01.nyt.com\/images\/2018\/09\/15\/business\/15DEBTS01\/merlin_138209730_5f3b5746-4962-4207-a24f-aea644a8636f-articleLarge.jpg?quality=75&auto=webp&disable=upscale" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected-metadata.json new file mode 100644 index 000000000..52b7f138d --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "By Nelson D. Schwartz", + "Direction": null, + "Excerpt": "Tax cuts, spending increases and higher interest rates could make it harder to respond to future recessions and deal with other needs.", + "Image": "https:\/\/static01.nyt.com\/images\/2018\/09\/15\/business\/15DEBTS01\/15DEBTS01-facebookJumbo.jpg", + "Title": "As Debt Rises, the Government Will Soon Spend More on Interest Than on the Military", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected.html new file mode 100644 index 000000000..855eb5595 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/expected.html @@ -0,0 +1,214 @@ +
+ +
+ + +

+ Tax cuts, spending increases and higher interest rates could make it harder to respond to future recessions and deal with other needs. +

+
+
+

Image +

+
+ Interest payments on the federal debt could surpass the Defense Department budget in 2023.CreditCreditJeon Heon-Kyun/EPA, via Shutterstock +
+
+
+ +
+
+
+

+ The federal government could soon pay more in interest on its debt than it spends on the military, Medicaid or children’s programs. +

+

+ The run-up in borrowing costs is a one-two punch brought on by the need to finance a fast-growing budget deficit, worsened by tax cuts and steadily rising interest rates that will make the debt more expensive. +

+

+ With less money coming in and more going toward interest, political leaders will find it harder to address pressing needs like fixing crumbling roads and bridges or to make emergency moves like pulling the economy out of future recessions. +

+

+ Within a decade, more than $900 billion in interest payments will be due annually, easily outpacing spending on myriad other programs. Already the fastest-growing major government expense, the cost of interest is on track to hit $390 billion next year, nearly 50 percent more than in 2017, according to the Congressional Budget Office. +

+
+
+

+ “It’s very much something to worry about,” said C. Eugene Steuerle, a fellow at the Urban Institute and a co-founder of the Urban-Brookings Tax Policy Center in Washington. “Everything else is getting squeezed.” +

+

+ Gradually rising interest rates would have made borrowing more expensive even without additional debt. But the tax cuts passed late last year have created a deeper hole, with the deficit increasing faster than expected. A budget bill approved in February that raised spending by $300 billion over two years will add to the financial pressure. +

+

+ The deficit is expected to total nearly $1 trillion next year — the first time it has been that big since 2012, when the economy was still struggling to recover from the financial crisis and interest rates were near zero. +

+
+ +
+

+ Deficit hawks have gone silent, even proposing changes that would exacerbate the deficit. House Republicans introduced legislation this month that would make the tax cuts permanent. +

+

+ “The issue has just disappeared,” said Senator Mark Warner, a Virginia Democrat. “There’s collective amnesia.” +

+
+
+

+ The combination, say economists, marks a journey into mostly uncharted financial territory. +

+

+ In the past, government borrowing expanded during recessions and waned in recoveries. That countercyclical policy has been a part of the standard Keynesian toolbox to combat downturns since the Great Depression. +

+

+ The deficit is soaring now as the economy booms, meaning the stimulus is pro-cyclical. The risk is that the government would have less room to maneuver if the economy slows. +

+
+ +
+

+ Aside from wartime or a deep downturn like the 1930s or 2008-9, “this sort of aggressive fiscal stimulus is unprecedented in U.S. history,” said Jeffrey Frankel, an economist at Harvard. +

+

+ Pouring gasoline on an already hot economy has resulted in faster growth — the economy expanded at an annualized rate of 4.2 percent in the second quarter. But Mr. Frankel warns that when the economy weakens, the government will find it more difficult to cut taxes or increase spending. +

+

+ Lawmakers might, in fact, feel compelled to cut spending as tax revenue falls, further depressing the economy. “There will eventually be another recession, and this increases the chances we will have to slam on the brakes when the car is already going too slowly,” Mr. Frankel said. +

+ +
+ +
+

+ Finding the money to pay investors who hold government debt will crimp other parts of the budget. In a decade, interest on the debt will eat up 13 percent of government spending, up from 6.6 percent in 2017. +

+

+ “By 2020, we will spend more on interest than we do on kids, including education, food stamps and aid to families,” said Marc Goldwein, senior policy director at the Committee for a Responsible Federal Budget, a research and advocacy organization. +

+
+
+

+ Interest costs already dwarf spending on many popular programs. For example, grants to students from low-income families for college total roughly $30 billion — about one-tenth of what the government will pay in interest this year. Interest payments will overtake Medicaid in 2020 and the Department of Defense budget in 2023. +

+

+ What’s more, the heavy burden of interest payments could make it harder for the government to repair aging infrastructure or take on other big new projects. +

+

+ Mr. Trump has called for spending $1 trillion on infrastructure, but Congress has not taken up that idea. +

+
+
+

+ More about the federal debt and the economy +

+ +
+
+ +

+ Until recently, ultralow interest rates, set by the Federal Reserve to support the economy, allowed lawmakers to borrow without fretting too much about the cost of that debt. +

+

+ But as the economy has strengthened, the Fed has gradually raised rates, starting in December 2015. The central bank is expected to push rates up again on Wednesday, and more increases are in store. +

+

+ “When rates went down to record lows, it allowed the government to take on more debt without paying more interest,” Mr. Goldwein said. “That party is ending.” +

+
+ +
+

+ Since the beginning of the year, the yield on the 10-year Treasury note has risen by more than half a percentage point, to 3.1 percent. The Congressional Budget Office estimates that the yield will climb to 4.2 percent in 2021. Given that the total public debt of the United States stands at nearly $16 trillion, even a small uptick in rates can cost the government billions. +

+ +
+
+

+ There’s no guarantee that these forecasts will prove accurate. If the economy weakens, rates might fall or rise only slightly, reducing interest payments. But rates could also overshoot the budget office forecast. +

+

+ Some members of Congress want to set the stage for even more red ink. Republicans in the House want to make last year’s tax cuts permanent, instead of letting some of them expire at the end of 2025. That would reduce federal revenue by an additional $631 billion over 10 years, according to the Tax Policy Center. +

+ +
+ +
+

+ Deficit hawks have warned for years that a day of reckoning is coming, exposing the United States to the kind of economic crisis that overtook profligate borrowers in the past like Greece or Argentina. +

+

+ But most experts say that isn’t likely because the dollar is the world’s reserve currency. As a result, the United States still has plenty of borrowing capacity left because the Fed can print money with fewer consequences than other central banks. +

+

+ And interest rates plunged over the last decade, even as the government turned to the market for trillions each year after the recession. That’s because Treasury bonds are still the favored port of international investors in any economic storm. +

+

+ “We exported a financial crisis a decade ago, and the world responded by sending us money,” said William G. Gale, a senior fellow at the Brookings Institution. +

+

+ But that privileged position has allowed politicians in both parties to avoid politically painful steps like cutting spending or raising taxes. +

+
+
+

+ That doesn’t mean rapidly rising interest costs and a bigger deficit won’t eventually catch up with us. +

+

+ Charles Schultze, chairman of the Council of Economic Advisers in the Carter administration, once summed up the danger of deficits with a metaphor. “It’s not so much a question of the wolf at the door, but termites in the woodwork.” +

+ +

+ Rather than simply splitting along party lines, lawmakers’ attitudes toward the deficit also depend on which party is in power. Republicans pilloried the Obama administration for proposing a large stimulus in the depths of the recession in 2009 and complained about the deficit for years. +

+

+ In 2013, Senator Mitch McConnell of Kentucky called the debt and deficit “the transcendent issue of our era.” By 2017, as Senate majority leader, he quickly shepherded the tax cut through Congress. +

+

+ Senator James Lankford, an Oklahoma Republican who warned of the deficit’s dangers in the past, nevertheless played down that threat on the Senate floor as the tax billed neared passage. +

+

+ “I understand it’s a risk, but I think it’s an appropriate risk to be able to say let’s allow Americans to keep more of their own money to invest in this economy,” he said. +

+

+ He also claimed the tax cuts would pay for themselves even as the Congressional Budget Office estimated that they would add $250 billion to the deficit on average from 2019 to 2024. +

+
+
+

+ In an interview, Mr. Lankford insisted that the jury was still out on whether the tax cuts would generate additional revenue, citing the strong economic growth recently. +

+

+ While the Republican about-face has been much more striking, Democrats have adjusted their position, too. +

+

+ Mr. Warner, the Virginia Democrat, called last year’s tax bill “the worst piece of legislation we have passed since I arrived in the Senate.” In 2009, however, when Congress passed an $800 billion stimulus bill backed by the Obama administration, he called it “a responsible mix of tax cuts and investments that will create jobs.” +

+

+ The difference, Mr. Warner said, was that the economy was near the precipice then. +

+

+ “There was virtual unanimity among economists that we needed a stimulus,” he said. “But a $2 trillion tax cut at the end of a business cycle with borrowed money won’t end well.” +

+
+
+
+ +
+

+ Nelson D. Schwartz has covered economics since 2012. Previously, he wrote about Wall Street and banking, and also served as European economic correspondent in Paris. He joined The Times in 2007 as a feature writer for the Sunday Business section. @NelsonSchwartz +

+
+

+ A version of this article appears in print on

, on Page

A

1

of the New York edition

with the headline:

What May Soon Exceed Cost of U.S. Military? Interest on U.S. Debt . Order Reprints | Today’s Paper | Subscribe +

+ +
+ +
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/source.html new file mode 100644 index 000000000..81a2a68c3 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/nytimes-4/source.html @@ -0,0 +1,3896 @@ + + + + + + As Debt Rises, the Government Will Soon Spend More on Interest Than on the Military - The New York Times + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+
+
+
+
+
+ +
+
+ +
Skip to contentSkip to site index +
+
+ Economy +
+
+ + +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + +
+
+
+
+
+ +
+

+ As Debt Rises, the Government Will Soon Spend More on Interest Than on the Military +

+
+

+ Tax cuts, spending increases and higher interest rates could make it harder to respond to future recessions and deal with other needs. +

+
+
+
+
+
+ Image +
+
+ Interest payments on the federal debt could surpass the Defense Department budget in 2023.CreditCreditJeon Heon-Kyun/EPA, via Shutterstock +
+
+
+
+
+
+
+
+

+ By Nelson D. Schwartz +

+
+
+
    +
  • + +
  • +
  • +
    + +
    +
  • +
+
+
+
+
+
+
+

+ The federal government could soon pay more in interest on its debt than it spends on the military, Medicaid or children’s programs. +

+

+ The run-up in borrowing costs is a one-two punch brought on by the need to finance a fast-growing budget deficit, worsened by tax cuts and steadily rising interest rates that will make the debt more expensive. +

+

+ With less money coming in and more going toward interest, political leaders will find it harder to address pressing needs like fixing crumbling roads and bridges or to make emergency moves like pulling the economy out of future recessions. +

+

+ Within a decade, more than $900 billion in interest payments will be due annually, easily outpacing spending on myriad other programs. Already the fastest-growing major government expense, the cost of interest is on track to hit $390 billion next year, nearly 50 percent more than in 2017, according to the Congressional Budget Office. +

+
+ +
+
+
+

+ “It’s very much something to worry about,” said C. Eugene Steuerle, a fellow at the Urban Institute and a co-founder of the Urban-Brookings Tax Policy Center in Washington. “Everything else is getting squeezed.” +

+

+ Gradually rising interest rates would have made borrowing more expensive even without additional debt. But the tax cuts passed late last year have created a deeper hole, with the deficit increasing faster than expected. A budget bill approved in February that raised spending by $300 billion over two years will add to the financial pressure. +

+

+ The deficit is expected to total nearly $1 trillion next year — the first time it has been that big since 2012, when the economy was still struggling to recover from the financial crisis and interest rates were near zero. +

+
+ +
+
+
+
+

+ Annual interest payments on the national debt are expected to triple over the next decade, according to the Congressional Budget Office. +

+
+
+ + + + +
+ +
+ +
+

+ $915 +

+

+ billion +

+
+
+

+ Interest payments on the national debt +

+
+
+

+ $900 +

+
+
+

+ billion +

+
+
+

+ 600 +

+
+
+

+ 300 +

+
+
+

+ $263 +

+

+ billion +

+
+
+

+ 0 +

+
+
+

+ ’17 +

+
+
+

+ ’18 +

+
+
+

+ ’19 +

+
+
+

+ ’20 +

+
+
+

+ ’21 +

+
+
+

+ ’22 +

+
+
+

+ ’23 +

+
+
+

+ ’24 +

+
+
+

+ ’25 +

+
+
+

+ ’26 +

+
+
+

+ ’27 +

+
+
+

+ ’28 +

+
+
+
+ +
+

+ Interest payments on the national debt +

+
+
+

+ $900 +

+
+
+

+ billion +

+
+
+

+ $915 +

+

+ billion +

+
+
+

+ 600 +

+
+
+

+ 300 +

+
+
+

+ $263 +

+

+ billion +

+
+
+

+ 0 +

+
+
+

+ ’17 +

+
+
+

+ ’18 +

+
+
+

+ ’19 +

+
+
+

+ ’20 +

+
+
+

+ ’21 +

+
+
+

+ ’22 +

+
+
+

+ ’23 +

+
+
+

+ ’24 +

+
+
+

+ ’25 +

+
+
+

+ ’26 +

+
+
+

+ ’27 +

+
+
+

+ ’28 +

+
+
+
+ + +
+
+

+ By The New York Times | Source: Congressional Budget Office +

+
+
+
+
+
+

+ Deficit hawks have gone silent, even proposing changes that would exacerbate the deficit. House Republicans introduced legislation this month that would make the tax cuts permanent. +

+

+ “The issue has just disappeared,” said Senator Mark Warner, a Virginia Democrat. “There’s collective amnesia.” +

+
+ +
+
+
+

+ The combination, say economists, marks a journey into mostly uncharted financial territory. +

+

+ In the past, government borrowing expanded during recessions and waned in recoveries. That countercyclical policy has been a part of the standard Keynesian toolbox to combat downturns since the Great Depression. +

+

+ The deficit is soaring now as the economy booms, meaning the stimulus is pro-cyclical. The risk is that the government would have less room to maneuver if the economy slows. +

+
+ +
+
+
+
+

+ Debt as a percentage of gross domestic product tends to increase during recessions and fall during recoveries. But the debt is increasing now, even as the economy is growing, because of tax cuts and spending increases. +

+
+
+ + + +
+ +
+ +
+

+ Public debt as a share of gross domestic product +

+
+
+

+ 100 +

+
+
+

+ % +

+
+
+

+ RECESSIONS +

+
+
+

+ PROJECTED +

+
+
+

+ 80 +

+
+
+

+ 60 +

+
+
+

+ 40 +

+
+
+

+ 20 +

+
+
+

+ 0 +

+
+
+

+ ’78 +

+
+
+

+ ’80 +

+
+
+

+ ’90 +

+
+
+

+ ’00 +

+
+
+

+ ’10 +

+
+
+

+ ’20 +

+
+
+

+ ’28 +

+
+
+
+ +
+

+ Public debt as a share of gross domestic product +

+
+
+

+ 100 +

+
+
+

+ % +

+
+
+

+ 80 +

+
+
+

+ 60 +

+
+
+

+ 40 +

+
+
+

+ 20 +

+
+
+

+ RECESSIONS +

+
+
+

+ PROJECTED +

+
+
+

+ 0 +

+
+
+

+ ’80 +

+
+
+

+ ’90 +

+
+
+

+ ’00 +

+
+
+

+ ’10 +

+
+
+

+ ’20 +

+
+
+

+ ’28 +

+
+
+
+ + +
+
+

+ By The New York Times | Source: Congressional Budget Office +

+
+
+
+
+
+

+ Aside from wartime or a deep downturn like the 1930s or 2008-9, “this sort of aggressive fiscal stimulus is unprecedented in U.S. history,” said Jeffrey Frankel, an economist at Harvard. +

+

+ Pouring gasoline on an already hot economy has resulted in faster growth — the economy expanded at an annualized rate of 4.2 percent in the second quarter. But Mr. Frankel warns that when the economy weakens, the government will find it more difficult to cut taxes or increase spending. +

+

+ Lawmakers might, in fact, feel compelled to cut spending as tax revenue falls, further depressing the economy. “There will eventually be another recession, and this increases the chances we will have to slam on the brakes when the car is already going too slowly,” Mr. Frankel said. +

+ +
+ +
+
+
+
+

+ Interest payments will make up 13 percent of the federal budget a decade from now, surpassing spending on Medicaid and defense. +

+
+
+ + + + +
+ +
+ +
+

+ Expenditures as a share of overall budget +

+
+
+

+ 15 +

+
+
+

+ % +

+
+
+

+ Net interest +

+
+
+

+ 13.0% +

+
+
+

+ Defense +

+
+
+

+ 10 +

+
+
+

+ Medicaid +

+
+
+

+ 6.6% +

+
+
+

+ 5 +

+
+
+

+ 0 +

+
+
+

+ ’17 +

+
+
+

+ ’18 +

+
+
+

+ ’19 +

+
+
+

+ ’20 +

+
+
+

+ ’21 +

+
+
+

+ ’22 +

+
+
+

+ ’23 +

+
+
+

+ ’24 +

+
+
+

+ ’25 +

+
+
+

+ ’26 +

+
+
+

+ ’27 +

+
+
+

+ ’28 +

+
+
+
+ +
+

+ Expenditures as a share of overall budget +

+
+
+

+ 15 +

+
+
+

+ % +

+
+
+

+ Net interest +

+
+
+

+ 13.0% +

+
+
+

+ Defense +

+
+
+

+ 10 +

+
+
+

+ Medicaid +

+
+
+

+ 6.6% +

+
+
+

+ 5 +

+
+
+

+ 0 +

+
+
+

+ ’17 +

+
+
+

+ ’18 +

+
+
+

+ ’19 +

+
+
+

+ ’20 +

+
+
+

+ ’21 +

+
+
+

+ ’22 +

+
+
+

+ ’23 +

+
+
+

+ ’24 +

+
+
+

+ ’25 +

+
+
+

+ ’26 +

+
+
+

+ ’27 +

+
+
+

+ ’28 +

+
+
+
+ + +
+
+

+ By The New York Times | Source: Congressional Budget Office +

+
+
+
+
+
+

+ Finding the money to pay investors who hold government debt will crimp other parts of the budget. In a decade, interest on the debt will eat up 13 percent of government spending, up from 6.6 percent in 2017. +

+

+ “By 2020, we will spend more on interest than we do on kids, including education, food stamps and aid to families,” said Marc Goldwein, senior policy director at the Committee for a Responsible Federal Budget, a research and advocacy organization. +

+
+ +
+
+
+

+ Interest costs already dwarf spending on many popular programs. For example, grants to students from low-income families for college total roughly $30 billion — about one-tenth of what the government will pay in interest this year. Interest payments will overtake Medicaid in 2020 and the Department of Defense budget in 2023. +

+

+ What’s more, the heavy burden of interest payments could make it harder for the government to repair aging infrastructure or take on other big new projects. +

+

+ Mr. Trump has called for spending $1 trillion on infrastructure, but Congress has not taken up that idea. +

+
+ +
+ +
+
+ +

+ Until recently, ultralow interest rates, set by the Federal Reserve to support the economy, allowed lawmakers to borrow without fretting too much about the cost of that debt. +

+

+ But as the economy has strengthened, the Fed has gradually raised rates, starting in December 2015. The central bank is expected to push rates up again on Wednesday, and more increases are in store. +

+

+ “When rates went down to record lows, it allowed the government to take on more debt without paying more interest,” Mr. Goldwein said. “That party is ending.” +

+
+ +
+
+
+
+

+ After bottoming out below 2 percent, the yield on the 10-year Treasury note has climbed to over 3 percent recently. +

+
+
+ + + + +
+ +
+ +
+

+ Yield on 10-year Treasury note +

+
+
+

+ 8 +

+
+
+

+ % +

+
+
+

+ MONTHLY +

+
+
+

+ RECESSIONS +

+
+
+

+ 6 +

+
+
+

+ 4 +

+
+
+

+ 2 +

+
+
+

+ 0 +

+
+
+

+ ’98 +

+
+
+

+ ’00 +

+
+
+

+ ’02 +

+
+
+

+ ’04 +

+
+
+

+ ’06 +

+
+
+

+ ’08 +

+
+
+

+ ’10 +

+
+
+

+ ’12 +

+
+
+

+ ’14 +

+
+
+

+ ’16 +

+
+
+

+ ’18 +

+
+
+
+ +
+

+ Yield on 10-year Treasury note +

+
+
+

+ 8 +

+
+
+

+ % +

+
+
+

+ MONTHLY +

+
+
+

+ RECESSIONS +

+
+
+

+ 6 +

+
+
+

+ 4 +

+
+
+

+ 2 +

+
+
+

+ 0 +

+
+
+

+ ’98 +

+
+
+

+ ’02 +

+
+
+

+ ’06 +

+
+
+

+ ’10 +

+
+
+

+ ’14 +

+
+
+

+ ’18 +

+
+
+
+ + +
+
+

+ By The New York Times | Source: Reuters +

+
+
+
+
+
+

+ Since the beginning of the year, the yield on the 10-year Treasury note has risen by more than half a percentage point, to 3.1 percent. The Congressional Budget Office estimates that the yield will climb to 4.2 percent in 2021. Given that the total public debt of the United States stands at nearly $16 trillion, even a small uptick in rates can cost the government billions. +

+
+ +
+
+
+

+ There’s no guarantee that these forecasts will prove accurate. If the economy weakens, rates might fall or rise only slightly, reducing interest payments. But rates could also overshoot the budget office forecast. +

+

+ Some members of Congress want to set the stage for even more red ink. Republicans in the House want to make last year’s tax cuts permanent, instead of letting some of them expire at the end of 2025. That would reduce federal revenue by an additional $631 billion over 10 years, according to the Tax Policy Center. +

+ +
+ +
+
+
+
+

+ The dollar has strengthened even as government borrowing has increased. +

+
+
+ + + + +
+ +
+ +
+

+ U.S. Dollar index +

+
+
+

+ 140 +

+
+
+

+ MONTHLY +

+
+
+

+ RECESSIONS +

+
+
+

+ 120 +

+
+
+

+ 100 +

+
+
+

+ 80 +

+
+
+

+ 60 +

+
+
+

+ ’98 +

+
+
+

+ ’00 +

+
+
+

+ ’02 +

+
+
+

+ ’04 +

+
+
+

+ ’06 +

+
+
+

+ ’08 +

+
+
+

+ ’10 +

+
+
+

+ ’12 +

+
+
+

+ ’14 +

+
+
+

+ ’16 +

+
+
+

+ ’18 +

+
+
+
+ +
+

+ U.S. Dollar index +

+
+
+

+ 140 +

+
+
+

+ MONTHLY +

+
+
+

+ RECESSIONS +

+
+
+

+ 120 +

+
+
+

+ 100 +

+
+
+

+ 80 +

+
+
+

+ 60 +

+
+
+

+ ’98 +

+
+
+

+ ’02 +

+
+
+

+ ’06 +

+
+
+

+ ’10 +

+
+
+

+ ’14 +

+
+
+

+ ’18 +

+
+
+
+ + +
+
+

+ By The New York Times | Source: Reuters +

+
+
+
+
+
+

+ Deficit hawks have warned for years that a day of reckoning is coming, exposing the United States to the kind of economic crisis that overtook profligate borrowers in the past like Greece or Argentina. +

+

+ But most experts say that isn’t likely because the dollar is the world’s reserve currency. As a result, the United States still has plenty of borrowing capacity left because the Fed can print money with fewer consequences than other central banks. +

+

+ And interest rates plunged over the last decade, even as the government turned to the market for trillions each year after the recession. That’s because Treasury bonds are still the favored port of international investors in any economic storm. +

+

+ “We exported a financial crisis a decade ago, and the world responded by sending us money,” said William G. Gale, a senior fellow at the Brookings Institution. +

+

+ But that privileged position has allowed politicians in both parties to avoid politically painful steps like cutting spending or raising taxes. +

+
+ +
+
+
+

+ That doesn’t mean rapidly rising interest costs and a bigger deficit won’t eventually catch up with us. +

+

+ Charles Schultze, chairman of the Council of Economic Advisers in the Carter administration, once summed up the danger of deficits with a metaphor. “It’s not so much a question of the wolf at the door, but termites in the woodwork.” +

+ +

+ Rather than simply splitting along party lines, lawmakers’ attitudes toward the deficit also depend on which party is in power. Republicans pilloried the Obama administration for proposing a large stimulus in the depths of the recession in 2009 and complained about the deficit for years. +

+

+ In 2013, Senator Mitch McConnell of Kentucky called the debt and deficit “the transcendent issue of our era.” By 2017, as Senate majority leader, he quickly shepherded the tax cut through Congress. +

+

+ Senator James Lankford, an Oklahoma Republican who warned of the deficit’s dangers in the past, nevertheless played down that threat on the Senate floor as the tax billed neared passage. +

+

+ “I understand it’s a risk, but I think it’s an appropriate risk to be able to say let’s allow Americans to keep more of their own money to invest in this economy,” he said. +

+

+ He also claimed the tax cuts would pay for themselves even as the Congressional Budget Office estimated that they would add $250 billion to the deficit on average from 2019 to 2024. +

+
+ +
+
+
+

+ In an interview, Mr. Lankford insisted that the jury was still out on whether the tax cuts would generate additional revenue, citing the strong economic growth recently. +

+

+ While the Republican about-face has been much more striking, Democrats have adjusted their position, too. +

+

+ Mr. Warner, the Virginia Democrat, called last year’s tax bill “the worst piece of legislation we have passed since I arrived in the Senate.” In 2009, however, when Congress passed an $800 billion stimulus bill backed by the Obama administration, he called it “a responsible mix of tax cuts and investments that will create jobs.” +

+

+ The difference, Mr. Warner said, was that the economy was near the precipice then. +

+

+ “There was virtual unanimity among economists that we needed a stimulus,” he said. “But a $2 trillion tax cut at the end of a business cycle with borrowed money won’t end well.” +

+
+ +
+
+
+
+
+
+
+

+ Nelson D. Schwartz has covered economics since 2012. Previously, he wrote about Wall Street and banking, and also served as European economic correspondent in Paris. He joined The Times in 2007 as a feature writer for the Sunday Business section. @NelsonSchwartz +

+
+
+
+
+ A version of this article appears in print on , on Page A1 of the New York edition with the headline: What May Soon Exceed Cost of U.S. Military? Interest on U.S. Debt . Order Reprints | Today’s Paper | Subscribe +
+
+
+ +
+
+
+
+

+ Advertisement +

+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + +
+
+
+ + + + + + +
+ +
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected-metadata.json new file mode 100644 index 000000000..b026cb40a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\n tempor incididunt ut labore et dolore magna aliqua.", + "Image": null, + "Title": "Remove aria-hidden elements test", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected.html new file mode 100644 index 000000000..8d2152d5b --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/expected.html @@ -0,0 +1,7 @@ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua.

+

Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat.

+
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/source.html new file mode 100644 index 000000000..1c558e6e7 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/remove-aria-hidden/source.html @@ -0,0 +1,19 @@ + + + + + Remove aria-hidden elements test + + +
+

Lorem

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua.

+

Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat.

+
+
+ + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected-images.json new file mode 100644 index 000000000..cae59d312 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected-images.json @@ -0,0 +1,4 @@ +[ + "https:\/\/static.seattletimes.com\/wp-content\/uploads\/2019\/04\/120028-1200x630.jpg", + "https:\/\/static.seattletimes.com\/wp-content\/uploads\/2019\/04\/120109-1020x680.jpg" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected-metadata.json new file mode 100644 index 000000000..7eaff99a2 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "April 28, 2019 at 6:01 am Updated April 29, 2019 at 3:33 pm", + "Direction": null, + "Excerpt": "The story of Whole Foods\u2019 halibut deal opens a window into Amazon\u2019s grocery strategy and draws a line from a Seattle industry with roots in the 19th century to the dominant economic force of the 21st.", + "Image": "https:\/\/static.seattletimes.com\/wp-content\/uploads\/2019\/04\/120028-1200x630.jpg", + "Title": "Alaskan halibut, caught by a century-old Seattle boat, provides a glimpse of Amazon\u2019s strategy with Whole Foods", + "SiteName": "The Seattle Times" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected.html new file mode 100644 index 000000000..27397d835 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/expected.html @@ -0,0 +1,179 @@ +
+

+ From the deck of his 106-year-old halibut schooner, undergoing a seasonal overhaul at Fisherman’s Terminal in Seattle, skipper Wade Bassi has better insight than most into what’s happening at Amazon-owned Whole Foods Market, at least as pertains to the product he knows best. +

+

+ While he doesn’t buy halibut much — he’s got a freezer full of it — Bassi, 43 years a fisherman, keeps an eye on how it’s handled and presented in the grocery stores and fish markets. +

+

+ “When you look at nice halibut, I mean it is pure white,” he said. “And it is flaky-looking, and it is beautiful. It’s translucent. If you’ve got that in the fish market, people are going to buy it.” +

+

+ A few days earlier, Whole Foods touted a rarely seen promotional price for halibut as part of its ongoing campaign to revise the grocery chain’s high-cost reputation while maintaining its image for quality and sustainability. +

+

+ “Whole Foods is one of the better ones, to be honest with you,” Bassi said. “But you know, Whole Foods, whole paycheck. … They usually do charge way more for everything than anywhere else. Which really surprises me that they’re selling this for $16-something a pound, because they’re not making anything on it.” +

+

+ Whole Foods’ halibut deal opens a window into Amazon’s grocery strategy as it seeks to combine the defining characteristics of each brand, leverage its juggernaut Prime membership program and take a larger share of the grocery business from competitors such as Walmart, Kroger and Costco. +

+ +

+ It also draws a long line from a major Seattle industry with roots in the 19th century to the dominant economic force of the 21st. +

+

+ Amazon bought Whole Foods in August 2017 for $13.7 billion, its largest acquisition and an aggressive move into the grocery business. +

+

+ The combination of the two has been steady, said Tom Forte, who follows Amazon as a managing director at the D.A. Davidson brokerage. In a few more years, he said, “You won’t recognize the original Whole Foods.” +

+

+ Within months of the acquisition, Forte said, Whole Foods was selling cheaper cage-free eggs and organic ground beef, prices it said were a result of the deal. +

+

+ Then came the integration of Prime, Amazon’s $119-a-year shipping and media-subscription program, which Amazon founder Jeff Bezos said last year had surpassed 100 million members. In Whole Foods, Prime operates as a hybrid of the customer-loyalty discount programs offered by most grocers — in which consumers trade details of their purchasing habits for lower prices — and a paid membership like at Costco or Sam’s Club. +

+

+ Whole Foods stores have been festooned with yellow and blue signs pointing out Prime member benefits, one of which was fresh halibut fillets priced at $16.99 a pound, albeit only for a week earlier this month. +

+ +

+ “I was shocked to see that level,” said Tyler Besecker, president of Mercer Island-based Dana F. Besecker Company, the largest buyer of Pacific halibut. The price, which was matched at Kroger-owned QFC stores in the region last week, is “as low as I’ve ever seen.” (Besecker does not currently supply Whole Foods.) +

+

+ Fresh halibut fillets routinely sell for $24 to $28 a pound, and often more. +

+

+ He said there’s little if any room for a profit at the promotional price offered by Whole Foods and QFC. “They might be selling those at cost or as loss leaders just to get people into the stores,” Besecker said. +

+ +

+ In the competitive grocery business, promotions like this happen all the time. The thinking is that shoppers will be attracted by the discount on a staple or a prestige item, and then fill their carts with other groceries sold at a profit. +

+

+ A Whole Foods spokeswoman declined to comment on pricing. The temporary halibut discount is one of more than 300 such Prime promotions Whole Foods plans in the next few months. The company also said it was lowering prices across the store, its third such announcement since the acquisition. +

+

+ At the seafood counter in the Whole Foods store on Westlake, surrounded by Amazon headquarters buildings, a sign advertised “First of the Season Fresh Alaskan Halibut” and sported the blue Marine Stewardship Council (MSC) Certified Sustainable Seafood label. +

+ +

+ Whole Foods has been a pioneer in sustainable-seafood marketing, beginning in 1999 when it began to stock fish with the MSC label. In the mid-2000s, Pacific halibut fishermen sought the certification — a system of third-party audits that tracks seafood from catch to market — and Whole Foods was there from the beginning. +

+

+ “They were the first ones to market the MSC halibut,” said Bob Alverson, head of the Fishing Vessel Owners Association, representing boats that catch halibut and black cod and a driver of the certification effort. “It turned into quite a marketing advantage. Whole Foods saw that early. They were focusing on sustainable, high-quality food products. They had quite a bit of foresight, I think, in that direction.” +

+

+ The certification comes with added costs borne by the fishermen and buyers, and passed on to consumers. But it’s also an assurance “that people are watching out for the resource,” he said. +

+ +

+ As it tries to convince people it has lower prices, Whole Foods has been very careful to maintain the reputation built on products like MSC-certified halibut. +

+
+
+ Amazon-owned Whole Foods touted a price cut on halibut as part of an announcement recently about lower prices on hundreds of items. (Ellen M. Banner / The Seattle Times) +
+ Amazon-owned Whole Foods touted a price cut on halibut as part of an announcement recently about lower prices on hundreds of items. (Ellen M. Banner / The Seattle Times) +
+
+
+

+ Whole Foods future +

+

+ New signs in stores appeared this month, spelling out the value proposition it’s trying to strike: “New lower prices. Same high standards,” reads one, against a background image of carrots. +

+

+ At the same time, the company claims its new prices and Prime deals have saved customers “hundreds of millions of dollars” since the Amazon acquisition. +

+ +

+ If prices are being lowered and the quality bar stays the same, something else has to give. +

+

+ Analysts provided a few theories: +

+

+ Amazon could be willing to accept losses or slimmer profits within Whole Foods, as it has done in other businesses, in an effort to expand its customer base. +

+

+ “Do they take the profit from their non-retail efforts, which today is primarily cloud computing, and then reinvest those profits to take share in grocery?” Forte said. +

+ +

+ That could eventually open up an avenue to growth as the rate of expansion slows in Amazon’s broader U.S. retail sales. +

+

+ “That’s why they need grocery to work,” Forte said. “Grocery’s a very big category.” +

+

+ Whole Foods could also press suppliers to reduce their prices, essentially cutting their profit. +

+ +

+ “The worry with that is that it puts the squeeze on the producer upstream,” said Ananth Iyer, a professor at Purdue University whose research includes sustainability in supply chains. If producers are squeezed too much, he noted, they may start to cut corners. +

+

+ So far, there’s no evidence this is happening in halibut, where fishery practices have been carefully managed with a goal of sustainability for nearly a century. Also, Whole Foods does not yet have the scale as a buyer to dictate prices the way a company like Costco does. +

+

+ Forte said that even if it did have such clout, this would be a risky strategy that would undermine the very attributes of the Whole Foods brand that make it most valuable. +

+

+ Another theory is that Amazon could apply more of its technology and expertise in logistics to create supply-chain efficiencies that would maintain its profits while benefiting producers and consumers, particularly with perishable grocery products, Iyer said. This is part of the promise of the acquisition in the first place. +

+

+ “That’s a powerful combination,” Forte said. “The sustainable, the organic, the healthier food — all those qualities of Whole Foods, with the supply-chain technology of Amazon. It plays to the strengths of both sides.” +

+

+ Forte said he expects Amazon to continue its aggressive moves on grocery pricing at Whole Foods. But he wonders when the price cuts will be broader, particularly as Amazon competes with the likes of Walmart and Kroger for a bigger slice of U.S. food and beverage retail sales, which totaled $726 billion in 2017. Whole Foods said it has lowered prices on hundreds of items, with an emphasis on fresh produce. +

+ +

+ Forte described his attempt after the acquisition to get the ingredients for Rice Krispies Treats at Whole Foods. It was perhaps doomed from the start: Whole Foods doesn’t carry Rice Krispies. But he found an organic brown rice puff cereal and organic marshmallows. They were “so wildly expensive that we didn’t finish the exercise. I took the kids to Walmart and bought the ingredients for a pittance,” Forte said. +

+

+ That points to the bigger question of how Amazon plans to position Whole Foods for the long term in its expanding array of physical retail-grocery formats. It now has 11 automated Go convenience stores and is rumored to be planning a new, low-priced grocery chain of its own that may deploy the same cashierless checkout technology. +

+

+ Meanwhile, Whole Foods is not opening any new 365 stores, a smaller, lower-priced version of the main brand highlighting the company’s private-label products. Whole Foods co-founder and CEO John Mackey said in an internal memo that the “price distinction between the two brands has become less relevant” as Whole Foods lowered its prices, Yahoo Finance reported earlier this year. +

+

+ Amazon, too, is finding success with a growing stable of private-label brands — it had more than 100 as of last July, according to Coresight Research, double the number in 2017. One of these, Solimo, sells generic versions of everything from K-Cup coffee pods to Epsom salts to garbage bags and racked up more than $6 million in sales in January alone, according to data analysis firm 1010data. +

+

+ Of course, there’s nothing generic about a “fresh, sustainable wild-caught halibut fillet.” +

+

+ Back on the schooner +

+

+ The day after Easter, Bassi and his crew — three family members and an unrelated father-and-son team — loaded up the Polaris, one of four century-old wooden schooners still chasing halibut out of Seattle. (The broader Washington-based halibut fleet numbers about 100 vessels.) Bassi’s father fished on the Polaris, which Bassi co-owns with Rolfe McCartney. Bassi’s grandfather fished halibut back when schooners carried small dories out to the fishing grounds, which made the landing of a fish that can grow to 500 pounds all the more exciting. +

+ +

+ The Polaris motored out of Fisherman’s Terminal and through the Ballard Locks to begin the three-day journey through the Inside Passage to Ketchikan, Alaska. There, they take on tons of ice and bait, herring for the black cod Bassi will target first, and later chum salmon, codfish or octopus for the halibut. +

+

+ From a base in Kodiak, Alaska, the Polaris makes a series of trips, at sea for a week or longer at a time, to fish as far away as Attu Island at the far western edge of the Aleutian Islands chain. “It’s a big range that we fish,” Bassi said. +

+

+ The Polaris will trail long lines of hooks, leaving them to soak for several hours before reeling them in. The fish are stunned, bled and dressed, and put on ice in the hold. It is this fishing method that contributes to the quality of the halibut and sustainability of the fishery, as it reduces by-catch — the inadvertent taking of other species. +

+

+ They negotiate to sell the fish with four or five buyers, such as Besecker, at a price that fluctuates throughout the season. This is a peak time of year for halibut, with consumers seeking out fresh fish for Easter and Mother’s Day, Besecker said. Fishermen are typically paid between $5 and $6 a pound for halibut. +

+

+ The Alaskan halibut fishery has its troubles — as nearly all fisheries do — but has been rationalized and managed successfully, particularly over the last quarter-century. Alverson, a commissioner on the Seattle-based International Pacific Halibut Commission, which has managed catch limits for U.S. and Canadian fishermen since 1924, described it as a stable but declining resource. +

+

+ This year, the halibut fishery in the Northern Pacific and Bering Sea is capped at 29.4 million pounds, with most of that allocated to commercial fishing and smaller amounts reserved for recreational and tribal fishing, as well as by-catch of other commercial fisheries. +

+ +

+ Alverson summed up the journey from a wooden fishing boat in the Bering Sea to the fish counter of a grocery store owned by a company that has redefined modern buying and selling: “It’s Seattle old school meets Seattle new school with Amazon.” +

+ + +
\ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/source.html new file mode 100644 index 000000000..f9a577e3c --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/seattletimes-1/source.html @@ -0,0 +1,1659 @@ + + + + + + + + + + + + + + + + + + + Alaskan halibut, caught by a century-old Seattle boat, provides a glimpse of Amazon’s strategy with Whole Foods | The Seattle Times + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+ +

+ Alaskan halibut, caught by a century-old Seattle boat, provides a glimpse of Amazon’s strategy with Whole Foods +

+ +
+ +
+ +
+

+ From the deck of his 106-year-old halibut schooner, undergoing a seasonal overhaul at Fisherman’s Terminal in Seattle, skipper Wade Bassi has better insight than most into what’s happening at Amazon-owned Whole Foods Market, at least as pertains to the product he knows best. +

+

+ While he doesn’t buy halibut much — he’s got a freezer full of it — Bassi, 43 years a fisherman, keeps an eye on how it’s handled and presented in the grocery stores and fish markets. +

+

+ “When you look at nice halibut, I mean it is pure white,” he said. “And it is flaky-looking, and it is beautiful. It’s translucent. If you’ve got that in the fish market, people are going to buy it.” +

+

+ A few days earlier, Whole Foods touted a rarely seen promotional price for halibut as part of its ongoing campaign to revise the grocery chain’s high-cost reputation while maintaining its image for quality and sustainability. +

+

+ “Whole Foods is one of the better ones, to be honest with you,” Bassi said. “But you know, Whole Foods, whole paycheck. … They usually do charge way more for everything than anywhere else. Which really surprises me that they’re selling this for $16-something a pound, because they’re not making anything on it.” +

+

+ Whole Foods’ halibut deal opens a window into Amazon’s grocery strategy as it seeks to combine the defining characteristics of each brand, leverage its juggernaut Prime membership program and take a larger share of the grocery business from competitors such as Walmart, Kroger and Costco. +

+
+
+ Advertising +
+
+
+
+
+
+
+
+
+
+
+
+
+

+ It also draws a long line from a major Seattle industry with roots in the 19th century to the dominant economic force of the 21st. +

+

+ Amazon bought Whole Foods in August 2017 for $13.7 billion, its largest acquisition and an aggressive move into the grocery business. +

+

+ The combination of the two has been steady, said Tom Forte, who follows Amazon as a managing director at the D.A. Davidson brokerage. In a few more years, he said, “You won’t recognize the original Whole Foods.” +

+

+ Within months of the acquisition, Forte said, Whole Foods was selling cheaper cage-free eggs and organic ground beef, prices it said were a result of the deal. +

+

+ Then came the integration of Prime, Amazon’s $119-a-year shipping and media-subscription program, which Amazon founder Jeff Bezos said last year had surpassed 100 million members. In Whole Foods, Prime operates as a hybrid of the customer-loyalty discount programs offered by most grocers — in which consumers trade details of their purchasing habits for lower prices — and a paid membership like at Costco or Sam’s Club. +

+

+ Whole Foods stores have been festooned with yellow and blue signs pointing out Prime member benefits, one of which was fresh halibut fillets priced at $16.99 a pound, albeit only for a week earlier this month. +

+
+
+ Advertising +
+
+
+
+
+
+
+

+ “I was shocked to see that level,” said Tyler Besecker, president of Mercer Island-based Dana F. Besecker Company, the largest buyer of Pacific halibut. The price, which was matched at Kroger-owned QFC stores in the region last week, is “as low as I’ve ever seen.” (Besecker does not currently supply Whole Foods.) +

+

+ Fresh halibut fillets routinely sell for $24 to $28 a pound, and often more. +

+

+ He said there’s little if any room for a profit at the promotional price offered by Whole Foods and QFC. “They might be selling those at cost or as loss leaders just to get people into the stores,” Besecker said. +

+
+

+ In the competitive grocery business, promotions like this happen all the time. The thinking is that shoppers will be attracted by the discount on a staple or a prestige item, and then fill their carts with other groceries sold at a profit. +

+

+ A Whole Foods spokeswoman declined to comment on pricing. The temporary halibut discount is one of more than 300 such Prime promotions Whole Foods plans in the next few months. The company also said it was lowering prices across the store, its third such announcement since the acquisition. +

+

+ At the seafood counter in the Whole Foods store on Westlake, surrounded by Amazon headquarters buildings, a sign advertised “First of the Season Fresh Alaskan Halibut” and sported the blue Marine Stewardship Council (MSC) Certified Sustainable Seafood label. +

+
+
+
+

+ Whole Foods has been a pioneer in sustainable-seafood marketing, beginning in 1999 when it began to stock fish with the MSC label. In the mid-2000s, Pacific halibut fishermen sought the certification — a system of third-party audits that tracks seafood from catch to market — and Whole Foods was there from the beginning. +

+

+ “They were the first ones to market the MSC halibut,” said Bob Alverson, head of the Fishing Vessel Owners Association, representing boats that catch halibut and black cod and a driver of the certification effort. “It turned into quite a marketing advantage. Whole Foods saw that early. They were focusing on sustainable, high-quality food products. They had quite a bit of foresight, I think, in that direction.” +

+

+ The certification comes with added costs borne by the fishermen and buyers, and passed on to consumers. But it’s also an assurance “that people are watching out for the resource,” he said. +

+ +

+ As it tries to convince people it has lower prices, Whole Foods has been very careful to maintain the reputation built on products like MSC-certified halibut. +

+
+
+ Amazon-owned Whole Foods touted a price cut on halibut as part of an announcement recently about lower prices on hundreds of items. (Ellen M. Banner / The Seattle Times) +
+ Amazon-owned Whole Foods touted a price cut on halibut as part of an announcement recently about lower prices on hundreds of items. (Ellen M. Banner / The Seattle Times) +
+
+
+

+ Whole Foods future +

+

+ New signs in stores appeared this month, spelling out the value proposition it’s trying to strike: “New lower prices. Same high standards,” reads one, against a background image of carrots. +

+

+ At the same time, the company claims its new prices and Prime deals have saved customers “hundreds of millions of dollars” since the Amazon acquisition. +

+
+
+ Advertising +
+
+
+

+ If prices are being lowered and the quality bar stays the same, something else has to give. +

+

+ Analysts provided a few theories: +

+

+ Amazon could be willing to accept losses or slimmer profits within Whole Foods, as it has done in other businesses, in an effort to expand its customer base. +

+

+ “Do they take the profit from their non-retail efforts, which today is primarily cloud computing, and then reinvest those profits to take share in grocery?” Forte said. +

+
+

+ That could eventually open up an avenue to growth as the rate of expansion slows in Amazon’s broader U.S. retail sales. +

+

+ “That’s why they need grocery to work,” Forte said. “Grocery’s a very big category.” +

+

+ Whole Foods could also press suppliers to reduce their prices, essentially cutting their profit. +

+
+
+ Advertising +
+
+
+
+
+
+
+

+ “The worry with that is that it puts the squeeze on the producer upstream,” said Ananth Iyer, a professor at Purdue University whose research includes sustainability in supply chains. If producers are squeezed too much, he noted, they may start to cut corners. +

+

+ So far, there’s no evidence this is happening in halibut, where fishery practices have been carefully managed with a goal of sustainability for nearly a century. Also, Whole Foods does not yet have the scale as a buyer to dictate prices the way a company like Costco does. +

+

+ Forte said that even if it did have such clout, this would be a risky strategy that would undermine the very attributes of the Whole Foods brand that make it most valuable. +

+

+ Another theory is that Amazon could apply more of its technology and expertise in logistics to create supply-chain efficiencies that would maintain its profits while benefiting producers and consumers, particularly with perishable grocery products, Iyer said. This is part of the promise of the acquisition in the first place. +

+

+ “That’s a powerful combination,” Forte said. “The sustainable, the organic, the healthier food — all those qualities of Whole Foods, with the supply-chain technology of Amazon. It plays to the strengths of both sides.” +

+

+ Forte said he expects Amazon to continue its aggressive moves on grocery pricing at Whole Foods. But he wonders when the price cuts will be broader, particularly as Amazon competes with the likes of Walmart and Kroger for a bigger slice of U.S. food and beverage retail sales, which totaled $726 billion in 2017. Whole Foods said it has lowered prices on hundreds of items, with an emphasis on fresh produce. +

+
+
+ Advertising +
+
+
+
+
+
+
+

+ Forte described his attempt after the acquisition to get the ingredients for Rice Krispies Treats at Whole Foods. It was perhaps doomed from the start: Whole Foods doesn’t carry Rice Krispies. But he found an organic brown rice puff cereal and organic marshmallows. They were “so wildly expensive that we didn’t finish the exercise. I took the kids to Walmart and bought the ingredients for a pittance,” Forte said. +

+

+ That points to the bigger question of how Amazon plans to position Whole Foods for the long term in its expanding array of physical retail-grocery formats. It now has 11 automated Go convenience stores and is rumored to be planning a new, low-priced grocery chain of its own that may deploy the same cashierless checkout technology. +

+

+ Meanwhile, Whole Foods is not opening any new 365 stores, a smaller, lower-priced version of the main brand highlighting the company’s private-label products. Whole Foods co-founder and CEO John Mackey said in an internal memo that the “price distinction between the two brands has become less relevant” as Whole Foods lowered its prices, Yahoo Finance reported earlier this year. +

+

+ Amazon, too, is finding success with a growing stable of private-label brands — it had more than 100 as of last July, according to Coresight Research, double the number in 2017. One of these, Solimo, sells generic versions of everything from K-Cup coffee pods to Epsom salts to garbage bags and racked up more than $6 million in sales in January alone, according to data analysis firm 1010data. +

+

+ Of course, there’s nothing generic about a “fresh, sustainable wild-caught halibut fillet.” +

+

+ Back on the schooner +

+

+ The day after Easter, Bassi and his crew — three family members and an unrelated father-and-son team — loaded up the Polaris, one of four century-old wooden schooners still chasing halibut out of Seattle. (The broader Washington-based halibut fleet numbers about 100 vessels.) Bassi’s father fished on the Polaris, which Bassi co-owns with Rolfe McCartney. Bassi’s grandfather fished halibut back when schooners carried small dories out to the fishing grounds, which made the landing of a fish that can grow to 500 pounds all the more exciting. +

+
+
+ Advertising +
+
+
+
+
+
+
+
+
+
+
+
+
+

+ The Polaris motored out of Fisherman’s Terminal and through the Ballard Locks to begin the three-day journey through the Inside Passage to Ketchikan, Alaska. There, they take on tons of ice and bait, herring for the black cod Bassi will target first, and later chum salmon, codfish or octopus for the halibut. +

+

+ From a base in Kodiak, Alaska, the Polaris makes a series of trips, at sea for a week or longer at a time, to fish as far away as Attu Island at the far western edge of the Aleutian Islands chain. “It’s a big range that we fish,” Bassi said. +

+

+ The Polaris will trail long lines of hooks, leaving them to soak for several hours before reeling them in. The fish are stunned, bled and dressed, and put on ice in the hold. It is this fishing method that contributes to the quality of the halibut and sustainability of the fishery, as it reduces by-catch — the inadvertent taking of other species. +

+

+ They negotiate to sell the fish with four or five buyers, such as Besecker, at a price that fluctuates throughout the season. This is a peak time of year for halibut, with consumers seeking out fresh fish for Easter and Mother’s Day, Besecker said. Fishermen are typically paid between $5 and $6 a pound for halibut. +

+

+ The Alaskan halibut fishery has its troubles — as nearly all fisheries do — but has been rationalized and managed successfully, particularly over the last quarter-century. Alverson, a commissioner on the Seattle-based International Pacific Halibut Commission, which has managed catch limits for U.S. and Canadian fishermen since 1924, described it as a stable but declining resource. +

+

+ This year, the halibut fishery in the Northern Pacific and Bering Sea is capped at 29.4 million pounds, with most of that allocated to commercial fishing and smaller amounts reserved for recreational and tribal fishing, as well as by-catch of other commercial fisheries. +

+
+
+ Advertising +
+
+
+
+
+
+
+

+ Alverson summed up the journey from a wooden fishing boat in the Bering Sea to the fish counter of a grocery store owned by a company that has redefined modern buying and selling: “It’s Seattle old school meets Seattle new school with Amazon.” +

+
+
+ More on Amazon + +
    +
    +

    + More +

    +
    +
    +
    + +
    +
    View Comments +
    +
    + You must be logged in to leave a comment. or . +
    +
    +

    + The opinions expressed in reader comments are those of the author only, and do not reflect the opinions of The Seattle Times. +

    +
    +
    +
    + +
    +
    +
    +
    + Advertising +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected-images.json new file mode 100644 index 000000000..61e175c39 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected-images.json @@ -0,0 +1,3 @@ +[ + "https:\/\/topicseed.com\/static\/9c97da26f6eeee98fc2e628ca3416226\/57090\/content-depth-seo.png" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected-metadata.json new file mode 100644 index 000000000..cfac45994 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": "Content writers and marketers find it hard to write a lot of content about a very specific topic. They lose a lot of points on their content depth because they would rather focus on pushing thin content about plenty of topics.", + "Image": "https:\/\/topicseed.com\/static\/9c97da26f6eeee98fc2e628ca3416226\/57090\/content-depth-seo.png", + "Title": "Content Depth \u2014 Write Comprehensively About Your Core Topics", + "SiteName": "topicseed" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected.html new file mode 100644 index 000000000..18cd12890 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/expected.html @@ -0,0 +1,93 @@ +
    + +

    + Content depth is an arbitrary score or rating of how comprehensive the coverage of a specific topic is within a piece of content. Content breadth is an arbitrary grading of how many related subjects are you covering within your content. +

    +

    + And this distinction is important to make and establish from the beginning. Effective topical authority can only be gained when you use both content depth and content breadth in your overall content strategy for rapid search engine optimization gains. However, because most content writers prefer to write a little bit about many things rather than write a lot about one thing, you end up with a too little substance spread very thin. +

    +

    + Content depth should be the urgent priority for your content marketing strategy, and clearly defined in your content briefs. Start by dominating your own core topics, before venturing across the pond and write about linked subject matters. Otherwise, you are the opposite of an authority as the definition states that an authority is “a person with extensive or specialized knowledge about a subject; an expert”. Lastly, do not mistake article depth vs. article length: a blog post’s extreme wordcount has nothing to do with its content depth. +

    +

    + Assess How Deep Is Your Content +

    +

    + The first task on your list, right now, is to shortlist your core topics. What are you trying to be an expert on? Then, go through each one of your pieces of content and understand how well each blog post is covering its focus topic(s). Not how many times specific keywords appear, or how well the article is outlined and structured. +

    +

    + Put yourself in the shoes of an ignorant reader who seeks information. Read your article. And ask yourself how in-depth was the content you have written? I know the excuse you will come up with: this was written for beginners, therefore, it shouldn’t be too in-depth. And you are correct. Not every blog post is about absolute content depth otherwise we would only write one 10,000-word-long article, once and for all. But then, how well your beginner-level content pointing to your expert-level content? +

    +

    + In other words, each article should reach an incredible level of content depth for its expertise level. And then, provide further reading (i.e. links) to gain more knowledge, and depth. A lot of content editors write a beginner’s blog post and wait to see it perform well in order to write a more advanced sequel. Wrong. Give all the value so search engines can grade you highly on their authority scale for your core topics. Yes, it is a risk and you may write a dozen of articles on a specific topic that will never really rank at the top of SERPs, but reaching content depth is the first step towards SEO gains. +

    +

    + Remember that skyscraper content and 10x content are not necessarily the answer. These content writing strategies state that in order to beat another piece of content, you need to write 10x more. Either in quantity with a 10x word count or in quality by putting times more information within your own piece of content. Such articles often become unreadable and discourage visitors from absorbing all the knowledge. The best alternative is the create pillar pages centered around core topics, and several articles dealing with each specific section in depth. This is deep content powered by a smart internal linking strategy and search engines love that in this day and age where attention spans are short! With that being said, avoid writing 600-word articles! +

    +

    + Rewrite With Content Depth In Mind +

    +

    + Once you know which articles are lacking depth of knowledge and information, it is time to rethink each one. For each article, make a list of what essential pieces of information or data are missing. Then decide where to fit them, and decide whether the article would benefit from a full rewrite or not. As a rule of thumb, if you need to change a third of your article, you may need to rewrite it entirely. Of course, this does not mean erasing all work done prior, but it means starting afresh! Trying to fit deep content into an existing blog post gives you constraints so doing it from scratch can actually be easier to fight thin content. +

    + +

    + As explained above, make sure you do not force yourself to write a much longer article to reach a magic word count. And if you do, it has to be natural. In many cases, articles written months or years ago may need some upkeeping: trimming the fat and removing parts that are not bringing much value. Replace these with your newer and deeper content. +

    +

    + All content writers know that when you open Google Docs, WordPress, or your text editor of choice, you will inevitably count your focus keywords’ frequency. Although I understand (yet question) the value of keywords in modern SEO, do not become obsessed with reaching a magic number for your keywords. No reader coming from Google is out there counting how often your keywords are appearing. And search engine algorithms will penalize you for writing for robots, rather than humans. +

    +

    + With the massive rise of voice searches, users tend to use full questions for their search queries. What used to be top bottled water brands is now OK google, what is the best bottled-water brand in Texas? The point being, keywords are losing traction to leave space for a more natural language understanding of a blog post’s textual content, and meaning. +

    +

    + Yes, Content Depth and Breadth Overlap +

    +

    + “A topic can be defined as the company it keeps.” A very accurate saying loved by ontologists within the fields of computational linguistics, and information science. In simpler terms, a topic and all the terminology it is encompassing will inevitably overlap with related topics. Which, in turn, will form topic clusters. +

    +

    + For example, it is obvious that despite being two different topics, digital advertising and content marketing share some common phrases and terms. Inevitably, a website picking one as its core topic will use words in some blog posts that will identify the article as belonging to both topics, with a specific weight for each. +

    +

    + A keyword, phrase, or term, is not a prisoner to a single concept at all. This is how algorithms in natural language understanding can understand how two topics are related (e.g. read about topic modeling). Each topic has a specific vocabulary, a list of words and phrases commonly used in its context, and some of these terms are present in different vocabularies. +

    +

    + Therefore, content depth and content breadth are not to be opposed. Content marketers should use both strategies in order to reach ultimate topical authority over their choice of subject matters. +

    +

    + Depth of Content = Quality + Frequency +

    +

    + Up until recently, long-form blog posts generally were evergreen articles that generated a constant stream of organic traffic for a website. This was a lead magnet generation strategy which worked well: hire a writer, include the right keywords, reach over a 5,000-word word count, and hit publish. Then, wait. +

    +

    + Nowadays, in-depth content requires more effort over time in order to pay off. Writing a big article, as good as it is, will not get your anywhere near the level of topical breadth required by Google to rank you first. Instead, your content marketing plan should be about having: +

    + +

    + Search engines also look at how often you publish about a specific topic, and when was the last time it was written about. Nobody likes a graveyard blog, it just makes the reader lose trust; as if the writer was not good enough, therefore had no traffic, before entirely giving up. Deep content requires a sustained effort on your part to always new find ways to write about a specific subject. Sure, it will be easy at first. But what about five years later? Well, you will still need to hit publish, all about the very same topics you already covered years ago. +

    +

    + Tools and platforms such as topicseed are here to help you find new article ideas pertaining to your core topics within a few clicks and a few minutes. The number of web pages, Wikipedia articles, and pieces of content, our machine-learning algorithms can analyze in seconds would take you months to digest. Our topicgraph finds closely related concepts in order for your domain to reach topical authority through content depth and content breadth. +

    +
    \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/source.html new file mode 100644 index 000000000..fca1c0081 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/topicseed-1/source.html @@ -0,0 +1,400 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Content Depth — Write Comprehensively About Your Core Topics | topicseed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +

    + Content Depth — Write Comprehensively About Your Core Topics +

    +

    + Content writers and marketers find it hard to write a lot of content about a very specific topic. They lose a lot of points on their content depth because they would rather focus on pushing thin content about plenty of topics. +

    +
      +
    • + On 6/13/2018 by @lazharichir +
    • +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +

    + Content depth is an arbitrary score or rating of how comprehensive the coverage of a specific topic is within a piece of content. Content breadth is an arbitrary grading of how many related subjects are you covering within your content. +

    +

    + And this distinction is important to make and establish from the beginning. Effective topical authority can only be gained when you use both content depth and content breadth in your overall content strategy for rapid search engine optimization gains. However, because most content writers prefer to write a little bit about many things rather than write a lot about one thing, you end up with a too little substance spread very thin. +

    +

    + Content depth should be the urgent priority for your content marketing strategy, and clearly defined in your content briefs. Start by dominating your own core topics, before venturing across the pond and write about linked subject matters. Otherwise, you are the opposite of an authority as the definition states that an authority is “a person with extensive or specialized knowledge about a subject; an expert”. Lastly, do not mistake article depth vs. article length: a blog post’s extreme wordcount has nothing to do with its content depth. +

    +

    + Assess How Deep Is Your Content +

    +

    + The first task on your list, right now, is to shortlist your core topics. What are you trying to be an expert on? Then, go through each one of your pieces of content and understand how well each blog post is covering its focus topic(s). Not how many times specific keywords appear, or how well the article is outlined and structured. +

    +

    + Put yourself in the shoes of an ignorant reader who seeks information. Read your article. And ask yourself how in-depth was the content you have written? I know the excuse you will come up with: this was written for beginners, therefore, it shouldn’t be too in-depth. And you are correct. Not every blog post is about absolute content depth otherwise we would only write one 10,000-word-long article, once and for all. But then, how well your beginner-level content pointing to your expert-level content? +

    +

    + In other words, each article should reach an incredible level of content depth for its expertise level. And then, provide further reading (i.e. links) to gain more knowledge, and depth. A lot of content editors write a beginner’s blog post and wait to see it perform well in order to write a more advanced sequel. Wrong. Give all the value so search engines can grade you highly on their authority scale for your core topics. Yes, it is a risk and you may write a dozen of articles on a specific topic that will never really rank at the top of SERPs, but reaching content depth is the first step towards SEO gains. +

    +

    + Remember that skyscraper content and 10x content are not necessarily the answer. These content writing strategies state that in order to beat another piece of content, you need to write 10x more. Either in quantity with a 10x word count or in quality by putting times more information within your own piece of content. Such articles often become unreadable and discourage visitors from absorbing all the knowledge. The best alternative is the create pillar pages centered around core topics, and several articles dealing with each specific section in depth. This is deep content powered by a smart internal linking strategy and search engines love that in this day and age where attention spans are short! With that being said, avoid writing 600-word articles! +

    +

    + Rewrite With Content Depth In Mind +

    +

    + Once you know which articles are lacking depth of knowledge and information, it is time to rethink each one. For each article, make a list of what essential pieces of information or data are missing. Then decide where to fit them, and decide whether the article would benefit from a full rewrite or not. As a rule of thumb, if you need to change a third of your article, you may need to rewrite it entirely. Of course, this does not mean erasing all work done prior, but it means starting afresh! Trying to fit deep content into an existing blog post gives you constraints so doing it from scratch can actually be easier to fight thin content. +

    +
    + +
    +

    + As explained above, make sure you do not force yourself to write a much longer article to reach a magic word count. And if you do, it has to be natural. In many cases, articles written months or years ago may need some upkeeping: trimming the fat and removing parts that are not bringing much value. Replace these with your newer and deeper content. +

    +

    + All content writers know that when you open Google Docs, WordPress, or your text editor of choice, you will inevitably count your focus keywords’ frequency. Although I understand (yet question) the value of keywords in modern SEO, do not become obsessed with reaching a magic number for your keywords. No reader coming from Google is out there counting how often your keywords are appearing. And search engine algorithms will penalize you for writing for robots, rather than humans. +

    +

    + With the massive rise of voice searches, users tend to use full questions for their search queries. What used to be top bottled water brands is now OK google, what is the best bottled-water brand in Texas? The point being, keywords are losing traction to leave space for a more natural language understanding of a blog post’s textual content, and meaning. +

    +

    + Yes, Content Depth and Breadth Overlap +

    +

    + “A topic can be defined as the company it keeps.” A very accurate saying loved by ontologists within the fields of computational linguistics, and information science. In simpler terms, a topic and all the terminology it is encompassing will inevitably overlap with related topics. Which, in turn, will form topic clusters. +

    +

    + For example, it is obvious that despite being two different topics, digital advertising and content marketing share some common phrases and terms. Inevitably, a website picking one as its core topic will use words in some blog posts that will identify the article as belonging to both topics, with a specific weight for each. +

    +

    + A keyword, phrase, or term, is not a prisoner to a single concept at all. This is how algorithms in natural language understanding can understand how two topics are related (e.g. read about topic modeling). Each topic has a specific vocabulary, a list of words and phrases commonly used in its context, and some of these terms are present in different vocabularies. +

    +

    + Therefore, content depth and content breadth are not to be opposed. Content marketers should use both strategies in order to reach ultimate topical authority over their choice of subject matters. +

    +

    + Depth of Content = Quality + Frequency +

    +

    + Up until recently, long-form blog posts generally were evergreen articles that generated a constant stream of organic traffic for a website. This was a lead magnet generation strategy which worked well: hire a writer, include the right keywords, reach over a 5,000-word word count, and hit publish. Then, wait. +

    +

    + Nowadays, in-depth content requires more effort over time in order to pay off. Writing a big article, as good as it is, will not get your anywhere near the level of topical breadth required by Google to rank you first. Instead, your content marketing plan should be about having: +

    +
      +
    • a comprehensive pillar page covering a unique topic, and +
    • +
    • + narrow-focused children articles to dig deeper. +
    • +
    +

    + Search engines also look at how often you publish about a specific topic, and when was the last time it was written about. Nobody likes a graveyard blog, it just makes the reader lose trust; as if the writer was not good enough, therefore had no traffic, before entirely giving up. Deep content requires a sustained effort on your part to always new find ways to write about a specific subject. Sure, it will be easy at first. But what about five years later? Well, you will still need to hit publish, all about the very same topics you already covered years ago. +

    +

    + Tools and platforms such as topicseed are here to help you find new article ideas pertaining to your core topics within a few clicks and a few minutes. The number of web pages, Wikipedia articles, and pieces of content, our machine-learning algorithms can analyze in seconds would take you months to digest. Our topicgraph finds closely related concepts in order for your domain to reach topical authority through content depth and content breadth. +

    +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    +
    +
    + + + + + + + + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected-images.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected-images.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected-metadata.json new file mode 100644 index 000000000..76403c342 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": null, + "Direction": null, + "Excerpt": "Emscripten now supports standalone Wasm files, which do not need JavaScript.", + "Image": null, + "Title": "standalone WebAssembly binaries using Emscripten \u00b7 V8", + "SiteName": null +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected.html new file mode 100644 index 000000000..ba1132111 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/expected.html @@ -0,0 +1,178 @@ +
    +

    + Emscripten has always focused first and foremost on compiling to the Web and other JavaScript environments like Node.js. But as WebAssembly starts to be used without JavaScript, new use cases are appearing, and so we've been working on support for emitting standalone Wasm files from Emscripten, that do not depend on the Emscripten JS runtime! This post explains why that's interesting. +

    +

    + Using standalone mode in Emscripten # +

    +

    + First, let's see what you can do with this new feature! Similar to this post let's start with a "hello world" type program that exports a single function that adds two numbers: +

    +
    // add.c
    #include <emscripten.h>

    EMSCRIPTEN_KEEPALIVE
    int add(int x, int y) {
    return x + y;
    }

    +

    + We'd normally build this with something like emcc -O3 add.c -o add.js which would emit add.js and add.wasm. Instead, let's ask emcc to only emit Wasm: +

    +
    emcc -O3 add.c -o add.wasm
    +
    +

    + When emcc sees we only want Wasm then it makes it "standalone" - a Wasm file that can run by itself as much as possible, without any JavaScript runtime code from Emscripten. +

    +

    + Disassembling it, it's very minimal - just 87 bytes! It contains the obvious add function +

    +
    (func $add (param $0 i32) (param $1 i32) (result i32)
    (i32.add
    (local.get $0)
    (local.get $1)
    )
    )
    +

    + and one more function, _start, +

    +
    (func $_start
    (nop)
    )
    +

    + _start is part of the WASI spec, and Emscripten's standalone mode emits it so that we can run in WASI runtimes. (Normally _start would do global initialization, but here we just don't need any so it's empty.) +

    +

    + Write your own JavaScript loader # +

    +

    + One nice thing about a standalone Wasm file like this is that you can write custom JavaScript to load and run it, which can be very minimal depending on your use case. For example, we can do this in Node.js: +

    +
    // load-add.js
    const binary = require('fs').readFileSync('add.wasm');

    WebAssembly.instantiate(binary).then(({ instance }) => {
    console.log(instance.exports.add(40, 2));
    });

    +

    + Just 4 lines! Running that prints 42 as expected. Note that while this example is very simplistic, there are cases where you simply don't need much JavaScript, and may be able to do better than Emscripten's default JavaScript runtime (which supports a bunch of environments and options). A real-world example of that is in zeux's meshoptimizer - just 57 lines, including memory management, growth, etc.! +

    +

    + Running in Wasm runtimes # +

    +

    + Another nice thing about standalone Wasm files is that you can run them in Wasm runtimes like wasmer, wasmtime, or WAVM. For example, consider this hello world: +

    +
    // hello.cpp
    #include <stdio.h>

    int main() {
    printf("hello, world!\n");
    return 0;
    }

    +

    + We can build and run that in any of those runtimes: +

    +
    $ emcc hello.cpp -O3 -o hello.wasm
    $ wasmer run hello.wasm
    hello, world!
    $ wasmtime hello.wasm
    hello, world!
    $ wavm run hello.wasm
    hello, world!
    +

    + Emscripten uses WASI APIs as much as possible, so programs like this end up using 100% WASI and can run in WASI-supporting runtimes (see notes later on what programs require more than WASI). +

    +

    + Building Wasm plugins # +

    +

    + Aside from the Web and the server, an exciting area for Wasm is plugins. For example, an image editor might have Wasm plugins that can perform filters and other operations on the image. For that type of use case you want a standalone Wasm binary, just like in the examples so far, but where it also has a proper API for the embedding application. +

    +

    + Plugins are sometimes related to dynamic libraries, as dynamic libraries are one way to implement them. Emscripten has support for dynamic libraries with the SIDE_MODULE option, and this has been a way to build Wasm plugins. The new standalone Wasm option described here is an improvement on that in several ways: First, a dynamic library has relocatable memory, which adds overhead if you don’t need it (and you don’t if you aren’t linking the Wasm with another Wasm after loading it). Second, standalone output is designed to run in Wasm runtimes as well, as mentioned earlier. +

    +

    + Okay, so far so good: Emscripten can either emit JavaScript + WebAssembly as it always did, and now it can also emit just WebAssembly by itself, which lets you run it in places that don't have JavaScript like Wasm runtimes, or you can write your own custom JavaScript loader code, etc. Now let's talk about the background and the technical details! +

    +

    + WebAssembly's two standard APIs # +

    +

    + WebAssembly can only access the APIs it receives as imports - the core Wasm spec has no concrete API details. Given the current trajectory of Wasm, it looks like there will be 3 main categories of APIs that people import and use: +

    + +

    + WebAssembly is in the interesting position of having two standardized sets of APIs. This does makes sense in that one is for the Web and one for the server, and those environments do have different requirements; for similar reasons Node.js does not have identical APIs to JavaScript on the Web. +

    +

    + However, there is more than the Web and the server, in particular there are also Wasm plugins. For one thing, plugins can run inside an application that may be on the Web (just like JS plugins) or off the Web; for another, regardless of where the embedding application is, a plugin environment is not a Web nor a server environment. So it's not immediately obvious which sets of APIs will be used - it may depend on the code being ported, the Wasm runtime being embedded, etc. +

    +

    + Let's unify as much as possible # +

    +

    + One concrete way Emscripten hopes to help here is that by using WASI APIs as much as possible we can avoid unnecessary API differences. As mentioned earlier, on the Web Emscripten code accesses Web APIs indirectly, through JavaScript, so where that JavaScript API could look like WASI, we'd be removing an unnecessary API difference, and that same binary can also run on the server. In other words, if Wasm wants to log some info, it needs to call into JS, something like this: +

    +
    wasm   =>   function musl_writev(..) { .. console.log(..) .. }
    +

    + musl_writev is an implementation of the Linux syscall interface that musl libc uses to write data to a file descriptor, and that ends up calling console.log with the proper data. The Wasm module imports and calls that musl_writev, which defines an ABI between the JS and the Wasm. That ABI is arbitrary (and in fact Emscripten has changed its ABI over time to optimize it). If we replace that with an ABI that matches WASI, we can get this: +

    +
    wasm   =>   function __wasi_fd_write(..) { .. console.log(..) .. }
    +

    + This isn't a big change, just requiring some refactoring of the ABI, and when running in a JS environment it doesn't matter much. But now the Wasm can run without the JS since that WASI API is recognized by WASI runtimes! That’s how the standalone Wasm examples from before work, just by refactoring Emscripten to use WASI APIs. +

    +

    + Another advantage of Emscripten using WASI APIs is that we can help the WASI spec by finding real-world issues. For example, we found that changing the WASI "whence" constants would be useful, and we've started some discussions around code size and POSIX compatibility. +

    +

    + Emscripten using WASI as much as possible is also useful in that it lets users use a single SDK to target Web, server, and plugin environments. Emscripten isn't the only SDK allowing that, as the WASI SDK's output can be run on the Web using the WASI Web Polyfill or Wasmer's wasmer-js, but Emscripten’s Web output is more compact, so it lets a single SDK be used without compromising Web performance. +

    +

    + Speaking of which, you can emit a standalone Wasm file from Emscripten with optional JS in a single command: +

    +
    emcc -O3 add.c -o add.js -s STANDALONE_WASM
    +
    +

    + That emits add.js and add.wasm. The Wasm file is standalone just like earlier when we only emitted a Wasm file by itself (STANDALONE_WASM was set automatically when we said -o add.wasm), but now in addition there is a JS file that can load and run it. The JS is useful for running it on the Web if you don't want to write your own JS for that. +

    +

    + Do we need non-standalone Wasm? # +

    +

    + Why does the STANDALONE_WASM flag exist? In theory Emscripten could always set STANDALONE_WASM, which would be simpler. But standalone Wasm files can't depend on JS, and that has some downsides: +

    + +

    + If you want to run both on the Web and elsewhere, and you want 100% optimal code size and startup times, you should make two separate builds, one with -s STANDALONE and one without. That's very easy as it's just flipping one flag! +

    +

    + Necessary API differences # +

    +

    + We saw that Emscripten uses WASI APIs as much as possible to avoid unnecessary API differences. Are there any necessary ones? Sadly, yes - some WASI APIs require tradeoffs. For example: +

    + +

    + In time WASI may add more POSIX support, a memory growth notification, etc. - WASI is still highly experimental and expected to change significantly. For now, to avoid regressions in Emscripten we do not emit 100% WASI binaries if you use certain features. In particular, opening files uses a POSIX method instead of WASI, which means that if you call fopen then the resulting Wasm file will not be 100% WASI - however, if all you do is use printf, which operates on the already-open stdout, then it will be 100% WASI, as in the "hello world" example we saw near the beginning, where Emscripten's output does run in WASI runtimes. +

    +

    + If it would be useful for users we can add a PURE_WASI option which would sacrifice code size in return for strict WASI compliance, but if that's not urgent (and most plugin use cases we’ve seen so far don’t need full file I/O) then maybe we can wait for WASI to improve to where Emscripten can remove these non-WASI APIs. That would be the best outcome, and we’re working towards that as you can see in the links above. +

    +

    + However, even if WASI does improve, there is no avoiding the fact that Wasm has two standardized APIs as mentioned earlier. In the future I expect Emscripten will call Web APIs directly using interface types, because that will be more compact than calling a WASI-looking JS API that then calls a Web API (as in the musl_writev example from before). We could have a polyfill or a translation layer of some sort to help here, but we wouldn't want to use it unnecessarily, so we will need separate builds for Web and WASI environments. (This is somewhat unfortunate; in theory this could have been avoided if WASI were a superset of Web APIs, but obviously that would have meant compromises on the server side.) +

    +

    + Current status # +

    +

    + Quite a lot works already! The main limitations are: +

    + +

    + You can still use all those in Emscripten's standalone mode, but the output will contain calls to JS runtime support code. As a result, it will not be 100% WASI (for similar reasons those features also do not work in the WASI SDK). Those Wasm files won't run in WASI runtimes, but you can use them on the Web and you can write your own JS runtime for them. You can also use them as plugins; for example, a game engine could have plugins that render using OpenGL, and the developer would compile them in standalone mode and then implement the OpenGL imports in the engine's Wasm runtime. Standalone Wasm mode still helps here because it makes the output as standalone as Emscripten can make it. +

    +

    + You may also find APIs that do have a non-JS replacement that we haven’t converted yet, as work is still ongoing. Please file bugs, and as always help is welcome! +

    +
    \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/source.html new file mode 100644 index 000000000..4a23d093f --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/v8-blog/source.html @@ -0,0 +1,259 @@ + + + + + + Outside the web: standalone WebAssembly binaries using Emscripten · V8 + + + + + + + + + + + + + +
    +
    +
    +

    + Outside the web: standalone WebAssembly binaries using Emscripten +

    +

    + Published · Tagged with WebAssembly tooling +

    +
    +
    +

    + Emscripten has always focused first and foremost on compiling to the Web and other JavaScript environments like Node.js. But as WebAssembly starts to be used without JavaScript, new use cases are appearing, and so we've been working on support for emitting standalone Wasm files from Emscripten, that do not depend on the Emscripten JS runtime! This post explains why that's interesting. +

    +

    + Using standalone mode in Emscripten # +

    +

    + First, let's see what you can do with this new feature! Similar to this post let's start with a "hello world" type program that exports a single function that adds two numbers: +

    +
    // add.c
    #include <emscripten.h>

    EMSCRIPTEN_KEEPALIVE
    int add(int x, int y) {
    return x + y;
    }
    +

    + We'd normally build this with something like emcc -O3 add.c -o add.js which would emit add.js and add.wasm. Instead, let's ask emcc to only emit Wasm: +

    +
    emcc -O3 add.c -o add.wasm
    +
    +

    + When emcc sees we only want Wasm then it makes it "standalone" - a Wasm file that can run by itself as much as possible, without any JavaScript runtime code from Emscripten. +

    +

    + Disassembling it, it's very minimal - just 87 bytes! It contains the obvious add function +

    +
    (func $add (param $0 i32) (param $1 i32) (result i32)
    (i32.add
    (local.get $0)
    (local.get $1)
    )
    )
    +

    + and one more function, _start, +

    +
    (func $_start
    (nop)
    )
    +

    + _start is part of the WASI spec, and Emscripten's standalone mode emits it so that we can run in WASI runtimes. (Normally _start would do global initialization, but here we just don't need any so it's empty.) +

    +

    + Write your own JavaScript loader # +

    +

    + One nice thing about a standalone Wasm file like this is that you can write custom JavaScript to load and run it, which can be very minimal depending on your use case. For example, we can do this in Node.js: +

    +
    // load-add.js
    const binary = require('fs').readFileSync('add.wasm');

    WebAssembly.instantiate(binary).then(({ instance }) => {
    console.log(instance.exports.add(40, 2));
    });
    +

    + Just 4 lines! Running that prints 42 as expected. Note that while this example is very simplistic, there are cases where you simply don't need much JavaScript, and may be able to do better than Emscripten's default JavaScript runtime (which supports a bunch of environments and options). A real-world example of that is in zeux's meshoptimizer - just 57 lines, including memory management, growth, etc.! +

    +

    + Running in Wasm runtimes # +

    +

    + Another nice thing about standalone Wasm files is that you can run them in Wasm runtimes like wasmer, wasmtime, or WAVM. For example, consider this hello world: +

    +
    // hello.cpp
    #include <stdio.h>

    int main() {
    printf("hello, world!\n");
    return 0;
    }
    +

    + We can build and run that in any of those runtimes: +

    +
    $ emcc hello.cpp -O3 -o hello.wasm
    $ wasmer run hello.wasm
    hello, world!
    $ wasmtime hello.wasm
    hello, world!
    $ wavm run hello.wasm
    hello, world!
    +

    + Emscripten uses WASI APIs as much as possible, so programs like this end up using 100% WASI and can run in WASI-supporting runtimes (see notes later on what programs require more than WASI). +

    +

    + Building Wasm plugins # +

    +

    + Aside from the Web and the server, an exciting area for Wasm is plugins. For example, an image editor might have Wasm plugins that can perform filters and other operations on the image. For that type of use case you want a standalone Wasm binary, just like in the examples so far, but where it also has a proper API for the embedding application. +

    +

    + Plugins are sometimes related to dynamic libraries, as dynamic libraries are one way to implement them. Emscripten has support for dynamic libraries with the SIDE_MODULE option, and this has been a way to build Wasm plugins. The new standalone Wasm option described here is an improvement on that in several ways: First, a dynamic library has relocatable memory, which adds overhead if you don’t need it (and you don’t if you aren’t linking the Wasm with another Wasm after loading it). Second, standalone output is designed to run in Wasm runtimes as well, as mentioned earlier. +

    +

    + Okay, so far so good: Emscripten can either emit JavaScript + WebAssembly as it always did, and now it can also emit just WebAssembly by itself, which lets you run it in places that don't have JavaScript like Wasm runtimes, or you can write your own custom JavaScript loader code, etc. Now let's talk about the background and the technical details! +

    +

    + WebAssembly's two standard APIs # +

    +

    + WebAssembly can only access the APIs it receives as imports - the core Wasm spec has no concrete API details. Given the current trajectory of Wasm, it looks like there will be 3 main categories of APIs that people import and use: +

    +
      +
    • + Web APIs: This is what Wasm programs use on the Web, which are the existing standardized APIs that JavaScript can use too. Currently these are called indirectly, through JS glue code, but in the future with interface types they will be called directly. +
    • +
    • + WASI APIs: WASI focuses on standardizing APIs for Wasm on the server. +
    • +
    • + Other APIs: Various custom embeddings will define their own application-specific APIs. For example, we gave the example earlier of an image editor with Wasm plugins that implement an API to do visual effects. Note that a plugin might also have access to “system” APIs, like a native dynamic library would, or it might be very sandboxed and have no imports at all (if the embedding just calls its methods). +
    • +
    +

    + WebAssembly is in the interesting position of having two standardized sets of APIs. This does makes sense in that one is for the Web and one for the server, and those environments do have different requirements; for similar reasons Node.js does not have identical APIs to JavaScript on the Web. +

    +

    + However, there is more than the Web and the server, in particular there are also Wasm plugins. For one thing, plugins can run inside an application that may be on the Web (just like JS plugins) or off the Web; for another, regardless of where the embedding application is, a plugin environment is not a Web nor a server environment. So it's not immediately obvious which sets of APIs will be used - it may depend on the code being ported, the Wasm runtime being embedded, etc. +

    +

    + Let's unify as much as possible # +

    +

    + One concrete way Emscripten hopes to help here is that by using WASI APIs as much as possible we can avoid unnecessary API differences. As mentioned earlier, on the Web Emscripten code accesses Web APIs indirectly, through JavaScript, so where that JavaScript API could look like WASI, we'd be removing an unnecessary API difference, and that same binary can also run on the server. In other words, if Wasm wants to log some info, it needs to call into JS, something like this: +

    +
    wasm   =>   function musl_writev(..) { .. console.log(..) .. }
    +

    + musl_writev is an implementation of the Linux syscall interface that musl libc uses to write data to a file descriptor, and that ends up calling console.log with the proper data. The Wasm module imports and calls that musl_writev, which defines an ABI between the JS and the Wasm. That ABI is arbitrary (and in fact Emscripten has changed its ABI over time to optimize it). If we replace that with an ABI that matches WASI, we can get this: +

    +
    wasm   =>   function __wasi_fd_write(..) { .. console.log(..) .. }
    +

    + This isn't a big change, just requiring some refactoring of the ABI, and when running in a JS environment it doesn't matter much. But now the Wasm can run without the JS since that WASI API is recognized by WASI runtimes! That’s how the standalone Wasm examples from before work, just by refactoring Emscripten to use WASI APIs. +

    +

    + Another advantage of Emscripten using WASI APIs is that we can help the WASI spec by finding real-world issues. For example, we found that changing the WASI "whence" constants would be useful, and we've started some discussions around code size and POSIX compatibility. +

    +

    + Emscripten using WASI as much as possible is also useful in that it lets users use a single SDK to target Web, server, and plugin environments. Emscripten isn't the only SDK allowing that, as the WASI SDK's output can be run on the Web using the WASI Web Polyfill or Wasmer's wasmer-js, but Emscripten’s Web output is more compact, so it lets a single SDK be used without compromising Web performance. +

    +

    + Speaking of which, you can emit a standalone Wasm file from Emscripten with optional JS in a single command: +

    +
    emcc -O3 add.c -o add.js -s STANDALONE_WASM
    +
    +

    + That emits add.js and add.wasm. The Wasm file is standalone just like earlier when we only emitted a Wasm file by itself (STANDALONE_WASM was set automatically when we said -o add.wasm), but now in addition there is a JS file that can load and run it. The JS is useful for running it on the Web if you don't want to write your own JS for that. +

    +

    + Do we need non-standalone Wasm? # +

    +

    + Why does the STANDALONE_WASM flag exist? In theory Emscripten could always set STANDALONE_WASM, which would be simpler. But standalone Wasm files can't depend on JS, and that has some downsides: +

    +
      +
    • We can't minify the Wasm import and export names, as the minification only works if both sides agree, the Wasm and what loads it. +
    • +
    • Normally we create the Wasm Memory in JS so that JS can start to use it during startup, which lets us do work in parallel. But in standalone Wasm we have to create the Memory in the Wasm. +
    • +
    • Some APIs are just easy to do in JS. For example __assert_fail, which is called when a C assertion fails, is normally implemented in JS. It takes just a single line, and even if you include the JS functions it calls, the total code size is quite small. On the other hand, in a standalone build we can't depend on JS, so we use musl's assert.c. That uses fprintf, which means it ends up pulling in a bunch of C stdio support, including things with indirect calls that make it hard to remove unused functions. Overall, there are many such details that end up making a difference in total code size. +
    • +
    +

    + If you want to run both on the Web and elsewhere, and you want 100% optimal code size and startup times, you should make two separate builds, one with -s STANDALONE and one without. That's very easy as it's just flipping one flag! +

    +

    + Necessary API differences # +

    +

    + We saw that Emscripten uses WASI APIs as much as possible to avoid unnecessary API differences. Are there any necessary ones? Sadly, yes - some WASI APIs require tradeoffs. For example: +

    +
      +
    • WASI does not support various POSIX features, like user/group/world file permissions, as a result of which you can't fully implement a (Linux) system ls for example (see details in that link). Emscripten's existing filesystem layer does support some of those things, so if we switched to WASI APIs for all filesystem operations then we'd be losing some POSIX support. +
    • +
    • WASI's path_open has a cost in code size because it forces extra permissions handling in the Wasm itself. That code is unnecessary on the Web. +
    • +
    • WASI doesn't provide a notification API for memory growth, and as a result, JS runtimes must constantly check if memory grew and if so update their views, on every import and export. To avoid that overhead, Emscripten provides a notification API, emscripten_notify_memory_growth, which you can see implemented in a single line in zeux's meshoptimizer that we mentioned earlier. +
    • +
    +

    + In time WASI may add more POSIX support, a memory growth notification, etc. - WASI is still highly experimental and expected to change significantly. For now, to avoid regressions in Emscripten we do not emit 100% WASI binaries if you use certain features. In particular, opening files uses a POSIX method instead of WASI, which means that if you call fopen then the resulting Wasm file will not be 100% WASI - however, if all you do is use printf, which operates on the already-open stdout, then it will be 100% WASI, as in the "hello world" example we saw near the beginning, where Emscripten's output does run in WASI runtimes. +

    +

    + If it would be useful for users we can add a PURE_WASI option which would sacrifice code size in return for strict WASI compliance, but if that's not urgent (and most plugin use cases we’ve seen so far don’t need full file I/O) then maybe we can wait for WASI to improve to where Emscripten can remove these non-WASI APIs. That would be the best outcome, and we’re working towards that as you can see in the links above. +

    +

    + However, even if WASI does improve, there is no avoiding the fact that Wasm has two standardized APIs as mentioned earlier. In the future I expect Emscripten will call Web APIs directly using interface types, because that will be more compact than calling a WASI-looking JS API that then calls a Web API (as in the musl_writev example from before). We could have a polyfill or a translation layer of some sort to help here, but we wouldn't want to use it unnecessarily, so we will need separate builds for Web and WASI environments. (This is somewhat unfortunate; in theory this could have been avoided if WASI were a superset of Web APIs, but obviously that would have meant compromises on the server side.) +

    +

    + Current status # +

    +

    + Quite a lot works already! The main limitations are: +

    +
      +
    • + WebAssembly limitations: Various features, like C++ exceptions, setjmp, and pthreads, depend on JavaScript due to Wasm limitations, and there is no good non-JS replacement yet. (Emscripten may start to support some of them using Asyncify, or maybe we'll just wait for native Wasm features to arrive to VMs.) +
    • +
    • + WASI limitations: Libraries and APIs like OpenGL and SDL don't have corresponding WASI APIs yet. +
    • +
    +

    + You can still use all those in Emscripten's standalone mode, but the output will contain calls to JS runtime support code. As a result, it will not be 100% WASI (for similar reasons those features also do not work in the WASI SDK). Those Wasm files won't run in WASI runtimes, but you can use them on the Web and you can write your own JS runtime for them. You can also use them as plugins; for example, a game engine could have plugins that render using OpenGL, and the developer would compile them in standalone mode and then implement the OpenGL imports in the engine's Wasm runtime. Standalone Wasm mode still helps here because it makes the output as standalone as Emscripten can make it. +

    +

    + You may also find APIs that do have a non-JS replacement that we haven’t converted yet, as work is still ongoing. Please file bugs, and as always help is welcome! +

    +
    + +
    +
    + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected-images.json new file mode 100644 index 000000000..e9012bd01 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected-images.json @@ -0,0 +1,3 @@ +[ + "https:\/\/cdn.vox-cdn.com\/thumbor\/7WyjCLC7n6i1IG2eJB06qi1o7kQ=\/0x148:2300x1352\/fit-in\/1200x630\/cdn.vox-cdn.com\/uploads\/chorus_asset\/file\/9871033\/Movies_end_of_year_2017.jpg" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected-metadata.json new file mode 100644 index 000000000..4d61d3bd9 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Alissa Wilkinson", + "Direction": null, + "Excerpt": "It was an extraordinary year for movies.", + "Image": "https:\/\/cdn.vox-cdn.com\/thumbor\/7WyjCLC7n6i1IG2eJB06qi1o7kQ=\/0x148:2300x1352\/fit-in\/1200x630\/cdn.vox-cdn.com\/uploads\/chorus_asset\/file\/9871033\/Movies_end_of_year_2017.jpg", + "Title": "How to watch the 21 best films of 2017", + "SiteName": "Vox" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected.html new file mode 100644 index 000000000..82740b180 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/expected.html @@ -0,0 +1,309 @@ +
    +

    + In the introduction to her review anthology For Keeps: 30 Years at the Movies, the legendary film critic Pauline Kael wrote, “I’m frequently asked why I don’t write my memoirs. I think I have.” She meant what most movie critics realize at some point: that reading your past reviews and revisiting the lists of films you liked most during the year reveals not just something about a particular year in cinema, but something about you as well. +

    +

    + That’s the feeling I get constructing my list of the best films of 2017, a year that overflowed with great films in every genre, from horror and romantic comedy to documentary and arthouse drama. Some of the films on my list have commonalities — ghosts, meditations on memory and interpersonal connection, and women who refuse to behave — but mostly they underscore just how vibrant cinema remains as an art form, even in the midst of massive cultural shifts in the industry and beyond. And it is a keen reminder to me of all the 2017 conversations I’ve had around and at the movies — and the ways I will never be the same. +

    +

    + Here are my top 21 films of 2017 and how to watch them at home, with 14 honorable mentions. +

    +

    + 21) Star Wars: The Last Jedi +

    +
    +

    + +

    +
    +

    + I am as shocked as anyone that a Star Wars movie found its way onto my list — but I was bowled over by The Last Jedi, which may be one of the series’ best. In the hands of writer-director Rian Johnson (who will also oversee a new Star Wars trilogy), The Last Jedi is beautiful to look at and keeps its eye on the relationships between characters and how they communicate with one another, in addition to the bigger galactic story. The same characters are back, but they seem infused with new life, and the galaxy with a new kind of hope. The movie’s best details are in the strong bonds that develop between characters, and I left the film with the realization that for the first time in my life, I loved a Star Wars movie. Now I understand the magic. +

    +

    + Star Wars: The Last Jedi is currently streaming on Netflix and available to digitally rent on Google Play and YouTube. +

    +

    + 20) Faces Places +

    +
    +

    + +

    +
    +

    + The unusual documentary Faces Places (in French, Visages Villages) turns on the friendship between the accomplished street artist JR and legendary film director Agnès Varda, whose work was central to the development of the French New Wave movement. The pair (whose difference in age is 55 years) met after years of admiring each other’s work and decided to create a documentary portrait of France — by making a number of actual portraits. The film chronicles a leg of the "Inside Outside Project," a roving art initiative in which JR makes enormous portraits of people he meets and pastes them onto buildings and walls. In the film, Varda joins him, and as they talk to people around the country, they grow in their understanding of themselves and of each other. The development of their friendship, which is both affectionate and mutually sharpening, forms Faces Places’ emotional center. +

    +

    + Faces Places is currently streaming on Netflix and available to digitally rent on Google Play and YouTube. +

    + +

    + 19) Ingrid Goes West +

    +
    +

    + +

    +
    +

    + Ingrid Goes West is a twisted and dark comedy — part addiction narrative, part stalker story — and yet it’s set in a world that’s almost pathologically cheery: the glossy, sunny, nourishing, superfood- and superlative-loving universe of Instagram celebrity. But despite Ingrid Goes West’s spot-on take on that world, the best thing about the film is that it refuses to traffic in lazy buzzwords and easy skewering, particularly at the expense of young women. Instead, the movie conveys that behind every Instagram image and meltdown is a real person, with real insecurities, real feelings, and real problems. And it recognizes that living a life performed in public can be its own kind of self-deluding prison. +

    +

    + Ingrid Goes West is currently streaming on Hulu and available to digitally rent on YouTube and Google Play. +

    +

    + 18) Lady Macbeth +

    +
    +

    + +

    +
    +

    + Lady Macbeth is no placid costume drama. Adapted from an 1865 Russian novella by Nikolai Leskov, the movie follows Katherine (the astounding Florence Pugh), a woman in the Lady Macbeth line characterized by a potent cocktail of very few scruples and a lot of determination. She's a chilling avatar for the ways that class and privilege — both obvious and hidden — insulate some people from the consequences of their actions while damning others. Lady Macbeth is also a dazzling directorial debut from William Oldroyd, a thrilling combination of sex, murder, intrigue, and power plays. It’s visually stunning, each frame composed so carefully and deliberately that the wildness and danger roiling just below the surface feels even more frightening. Each scene ratchets up the tension to an explosive, chilling end. +

    +

    + Lady Macbeth is currently streaming on HBO Go and HBO Now, and it is available to digitally rent on Amazon Prime, Vudu, YouTube, iTunes, and Google Play. +

    +

    + 17) BPM (Beats Per Minute) +

    +
    +

    + +

    +
    +

    + BPM (Beats Per Minute) is a remarkably tender and stirring story of the Paris chapter of ACT UP, an AIDS activism group, and the young people who found themselves caught in the crosshairs of the AIDS crisis in the early 1990s. The film follows both the group's actions and the individual members’ shifting relationships to one another — enemies becoming friends, friends becoming lovers, lovers becoming caretakers — as well as their struggles with the disease wracking their community. As an account of the period, it’s riveting; as an exploration of life and love set at the urgent intersection of the political and the personal, it’s devastating. +

    +

    + BPM (Beats Per Minute) is currently streaming on Hulu and available to digitally rent on Google Play and YouTube. +

    +

    + 16) The Big Sick +

    +
    +

    + +

    +
    +

    + Few 2017 movies could top the charm and tenderness of The Big Sick, which hits all the right romantic comedy notes with one unusual distinction: It feels like real life. That’s probably because The Big Sick is written by real-life married couple Emily V. Gordon and Silicon Valley's Kumail Nanjiani, and based on their real-life romance. The Big Sick — which stars Nanjiani as a version of himself, alongside Zoe Kazan as Emily — is funny and sweet while not backing away from matters that romantic comedies don’t usually touch on, like serious illness, struggles in long-term marriages, and religion. As it tells the couple’s story, which takes a serious turn when Emily falls ill with a mysterious infection and her parents (played by Holly Hunter and Ray Romano) come to town, it becomes a funny and wise story about real love. +

    +

    + The Big Sick is currently streaming on Amazon Prime and available to digitally rent on iTunes, Vudu, Amazon, YouTube, and Google Play. +

    +

    + 15) Mother! +

    +
    +

    + +

    +
    +

    + There’s so much pulsing beneath the surface of Mother! that it’s hard to grab on to just one theme as what it “means.” It’s full-on apocalyptic fiction, and like all stories of apocalypse, it’s intended to draw back the veil on reality and show us what’s really beneath. And this movie gets wild: If its gleeful cracking apart of traditional theologies doesn’t get you (there’s a lot of Catholic folk imagery here, complete with an Ash Wednesday-like mud smearing on the foreheads of the faithful), its bonkers scenes of chaos probably will. Mother! is a movie designed to provoke fury, ecstasy, madness, catharsis, and more than a little awe. Watching it, and then participating in the flurry of arguments and discussions unpacking it, was among my best moviegoing experiences of 2017. +

    +

    + Mother! is available to digitally purchase on Google Play and YouTube. +

    +

    + 14) A Ghost Story +

    +
    +

    + +

    +
    +

    + Director David Lowery filmed A Ghost Story in secret, then premiered it at the Sundance Film Festival to critical acclaim. The movie starts out being about a grieving widow (Rooney Mara) trying to live through the pain of losing her beloved husband, but it soon shifts focus to the ghost of her husband (Casey Affleck, covered in a sheet), evolving into a compelling rumination on the nature of time, memory, history, and the universe. Bathed in warm humor and wistful longing, it's a film that stays with you long after it’s over, a lingering reminder of the inextricable link between love and place. +

    +

    + A Ghost Story is available to digitally rent on iTunes, Vudu, Amazon, Google Play, and YouTube. +

    +

    + 13) The Square +

    +
    +

    + +

    +
    + +

    + The Square is currently streaming on Hulu and available to digitally rent on Google Play and YouTube. +

    +

    + 12) Dunkirk +

    +
    +

    + +

    +
    +

    + Dunkirk, a true cinematic achievement from acclaimed director Christopher Nolan, backs off conventional notions of narrative and chronology as much as possible, while leaning headfirst into everything else that makes a movie a visceral work of art aimed at the senses: the images, the sounds, the scale, the swelling vibrations of it all. You can’t smell the sea spray, but your brain may trick you into thinking you can. Nolan’s camera pushes the edges of the screen as far as it can as Dunkirk engulfs the audience in something that feels like a lot more than a war movie. It’s a symphony for the brave and broken, and it resolves in a major key — but one with an undercurrent of sorrow, and of sober warning. Courage in the face of danger is not just for characters in movies. +

    +

    + Dunkirk is currently streaming on HBO Go and HBO Now, and available to digitally rent on Google Play and YouTube. +

    +

    + 11) Rat Film +

    +
    +

    + +

    +
    +

    + Rat Film is about rats, yes — and rat poison experts and rat hunters and people who keep rats as pets. But it’s also about the history of eugenics, dubious science, “redlining,” and segregated housing in Baltimore. All these pieces come together to form one big essay, where the meaning of each vignette only becomes clearer in light of the whole. It’s a fast-paced, no-holds-barred exploration of a damning history, and it accrues meaning as the images, sounds, and text pile up. +

    +

    + Rat Film is available to digitally rent on YouTube and Google Play. +

    +

    + 10) A Quiet Passion +

    +
    +

    + +

    +
    +

    + A Quiet Passion is technically a biographical film about Emily Dickinson, but it transcends its genre to become something more like poetry. It’s a perplexing and challenging film, crafted without the traditional guardrails that guide most biographical movies — dates, times, major accomplishments, and so on. Time slips away in the film almost imperceptibly, and the narrative arc doesn’t yield easily to the viewer. Cynthia Nixon plays Emily Dickinson, whose poetry and life is a perfect match for the signature style of director Terence Davies: rich in detail, deeply enigmatic, and weighed down with a kind of sparkling, joy-tinged sorrow. A Quiet Passion is a portrait, both visual and narrative, of the kind of saint most modern people can understand: one who is certain of her uncertainty, and yearning to walk the path on which her passion and longing meet. +

    +

    + A Quiet Passion is currently streaming on Amazon Prime and available to digitally rent or purchase on iTunes, Vudu, Amazon, YouTube, and Google Play. +

    +

    + 9) Columbus +

    +
    +

    + +

    +
    +

    + Columbus is a stunner of a debut from video essayist turned director Kogonada. Haley Lu Richardson stars as Casey, a young woman living in Columbus, Indiana, who cares for her mother, works at a library, and harbors a passion for architecture. (Columbus is a mecca for modernist architecture scholars and enthusiasts.) When a visiting architecture scholar falls into a coma in Columbus, his estranged son Jin (John Cho) arrives to wait for him and strikes up a friendship with Casey, who starts to show him her favorite buildings. The two begin to unlock something in each other that’s hard to define but life-changing for both. Columbus is beautiful and subtle, letting us feel how the places we build and the people we let near us move and mold us. +

    +

    + Columbus is currently streaming on Hulu and available to rent on Google Play and YouTube. +

    +

    + 8) The Florida Project +

    +
    +

    + +

    +
    +

    + Sean Baker’s The Florida Project unfolds at first like a series of sketches about the characters who live in a purple-painted, $35-a-night motel called the Magic Castle down the street from Disney World. The film is held together by the hysterical antics of a kid named Moonee and her pack of young friends, as well as long-suffering hotel manager Bobby (a splendid, warm Willem Dafoe), who tries to put up with it all while keeping some kind of order. But as The Florida Project goes on, a narrative starts to form, one that chronicles with heartbreaking attention the sort of dilemmas that face poor parents and their children in America, and the broken systems that try to cope with impossible situations. +

    +

    + The Florida Project is currently streaming on Amazon Prime and available to digitally rent on YouTube, Vudu, and Google Play. +

    +

    + 7) Call Me by Your Name +

    +
    +

    + +

    +
    +

    + Luca Guadagnino’s gorgeous film Call Me by Your Name adapts André Aciman’s 2007 novel about a precocious 17-year-old named Elio (Timothée Chalamet), who falls in lust and love with his father’s 24-year-old graduate student Oliver (Armie Hammer). It’s remarkable for how it turns literature into pure cinema, all emotion and image and heady sensation. Set in 1983 in Northern Italy, Call Me by Your Name is less about coming out than coming of age, but it also captures a particular sort of love that’s equal parts passion and torment, a kind of irrational heart fire that opens a gate into something longer-lasting. The film is a lush, heady experience for the body, but it’s also an arousal for the soul. +

    +

    + Call Me By Your Name is available to digitally purchase on Amazon, YouTube, and Google Play. +

    +

    + 6) Personal Shopper +

    +
    +

    + +

    +
    +

    + In her second collaboration with French director Olivier Assayas, Kristen Stewart plays a personal shopper to a wealthy socialite, with a sideline as an amateur ghost hunter who’s searching for her dead twin brother. Personal Shopper is deeper than it seems at first blush, a meditation on grief and an exploration of “between” places — on the fringes of wealth, and in the space between life and death. Some souls are linked in a way that can’t be shaken, and whether or not there’s an afterlife doesn’t change the fact that we see and sense them everywhere. (Personal Shopper also has one of the most tense extended scenes involving text messaging ever seen onscreen.) +

    +

    + Personal Shopper is currently streaming on Showtime and available to rent on Vudu, YouTube, Amazon, iTunes, and Google Play. +

    +

    + 5) Princess Cyd +

    +
    +

    + +

    +
    +

    + Stephen Cone is a master of small, carefully realized filmmaking; his earlier films such as The Wise Kids and Henry Gamble’s Birthday Party combine an unusual level of empathy for his characters with an unusual combination of interests: love, desire, sexual awakenings, and religion. Princess Cyd is his most accomplished film yet, about a young woman named Cyd (Jessie Pinnick) who finds herself attracted to Katie (Malic White), a barista, while visiting her Aunt Miranda (Rebecca Spence, playing a character modeled on the author Marilynne Robinson) in Chicago. As she works through her own sexual awakening with Katie, Cyd unwinds some of the ways Miranda’s life has gotten too safe. They provoke each other while forming a bond and being prodded toward a bigger understanding of the world. It is a graceful and honest film, and it feels like a modest miracle. +

    +

    + Princess Cyd is currently streaming on Netflix and available to digitally rent on Google Play and YouTube. +

    +

    + 4) Get Out +

    +
    +

    + +

    +
    +

    + Racism is sinister, frightening, and deadly. But Get Out (a stunning directorial debut from Key & Peele's Jordan Peele) isn’t about the blatantly, obviously scary kind of racism — burning crosses and lynchings and snarling hate. Instead, it’s interested in showing how the parts of racism that try to be aggressively unscary are just as horrifying, and it’s interested in making us feel that horror in a visceral, bodily way. In the tradition of the best classic social thrillers, Get Out takes a topic that is often approached cerebrally — casual racism — and turns it into something you feel in your tummy. And it does it with a wicked sense of humor. +

    +

    + Get Out is currently streaming on HBO Go and HBO Now, and is available to digitally rent on iTunes, Amazon, Google Play, YouTube, and Vudu. +

    +

    + 3) The Work +

    +
    +

    + +

    +
    +

    + The Work is an outstanding, astonishing accomplishment and a viewing experience that will leave you shaken (but in a good way). At Folsom Prison in California, incarcerated men regularly participate in group therapy, and each year other men from the “outside” apply to participate in an intense four-day period of group therapy alongside Folsom’s inmates. The Work spends almost all of its time inside the room where that therapy happens, observing the strong, visceral, and sometimes violent emotions the men feel as they expose the hurt and raw nerves that have shaped how they encounter the world. Watching is not always easy, but by letting us peek in, the film invites viewers to become part of the experience — as if we, too, are being asked to let go. +

    +

    + The Work is streaming on Topic.com and available to digitally rent on Google Play and YouTube. +

    +

    + 2) Ex Libris +

    +
    +

    + +

    +
    +

    + Frederick Wiseman is one of the towering giants of nonfiction film, a keen observer of American institutions — ranging from prisons to dance companies to welfare offices — for the past half-century. Ex Libris is his mesmerizing look at the New York Public Library and the many functions it fills, which go far beyond housing books. Wiseman works in the observational mode, which means his films contain no captions, dates, or talking-head interviews: We just see what his camera captured, which in this case includes community meetings, benefit dinners, after-school programs, readings with authors and scholars (including Richard Dawkins and Ta-Nehisi Coates), and NYPL patrons going about their business in the library’s branches all over the city. The result is almost hypnotic and, perhaps surprisingly, deeply moving. It makes a case for having faith in the public institutions where ordinary people work — away from the limelight, without trying to score political points — in order to make our communities truly better. +

    +

    + Ex Libris will air on PBS in the fall and then be available to cardholders in many library systems across the country via Kanopy. +

    +

    + 1) Lady Bird +

    +
    +

    + +

    +
    +

    + Lady Bird topped my list almost instantly, and only rose in my estimation on repeated viewings. For many who saw it (including me), it felt like a movie made not just for but about me. Lady Bird is a masterful, exquisite coming-of-age comedy starring the great Saoirse Ronan as Christine — or “Lady Bird,” as she’s re-christened herself — and it’s as funny, smart, and filled with yearning as its heroine. Writer-director Greta Gerwig made the film as an act of love, not just toward her hometown of Sacramento but also toward girlhood, and toward the feeling of always being on the outside of wherever real life is happening. Lady Bird is the rare movie that manages to be affectionate, entertaining, hilarious, witty, and confident. And one line from it struck me as the guiding principle of many of the year’s best films: “Don’t you think they are the same thing? Love, and attention?” +

    +

    + Lady Bird is currently streaming on Amazon Prime and available to digitally rent on Amazon, Google Play, and YouTube. +

    +

    + Honorable mentions: Marjorie Prime, Phantom Thread, Casting JonBenet, The Post, The Shape of Water, Logan Lucky, I, Tonya, The Lost City of Z, Graduation, Spettacolo, Loveless, Restless Creature: Wendy Whelan, In Transit, The Reagan Show +

    +
    \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/source.html new file mode 100644 index 000000000..9e407bc38 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-1/source.html @@ -0,0 +1,1319 @@ + + + + + How to watch the 21 best films of 2017 - Vox + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + clock + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + menu + + + + + + more-arrow + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + no + + + + + + yes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +

    + The 21 best movies of 2017 +

    +
    +

    + How to watch the greatest movies of the year, from Lady Bird and Dunkirk to Get Out and The Big Sick. +

    + +
    + +
    +
    +
    +
    + Javier Zarracina/Vox +
    + +
    +

    + In the introduction to her review anthology For Keeps: 30 Years at the Movies, the legendary film critic Pauline Kael wrote, “I’m frequently asked why I don’t write my memoirs. I think I have.” She meant what most movie critics realize at some point: that reading your past reviews and revisiting the lists of films you liked most during the year reveals not just something about a particular year in cinema, but something about you as well. +

    +

    + That’s the feeling I get constructing my list of the best films of 2017, a year that overflowed with great films in every genre, from horror and romantic comedy to documentary and arthouse drama. Some of the films on my list have commonalities — ghosts, meditations on memory and interpersonal connection, and women who refuse to behave — but mostly they underscore just how vibrant cinema remains as an art form, even in the midst of massive cultural shifts in the industry and beyond. And it is a keen reminder to me of all the 2017 conversations I’ve had around and at the movies — and the ways I will never be the same. +

    +

    + Here are my top 21 films of 2017 and how to watch them at home, with 14 honorable mentions. +

    +

    + 21) Star Wars: The Last Jedi +

    +
    +
    + +
    +
    +

    + I am as shocked as anyone that a Star Wars movie found its way onto my list — but I was bowled over by The Last Jedi, which may be one of the series’ best. In the hands of writer-director Rian Johnson (who will also oversee a new Star Wars trilogy), The Last Jedi is beautiful to look at and keeps its eye on the relationships between characters and how they communicate with one another, in addition to the bigger galactic story. The same characters are back, but they seem infused with new life, and the galaxy with a new kind of hope. The movie’s best details are in the strong bonds that develop between characters, and I left the film with the realization that for the first time in my life, I loved a Star Wars movie. Now I understand the magic. +

    +

    + Star Wars: The Last Jedi is currently streaming on Netflix and available to digitally rent on Google Play and YouTube. +

    +

    + 20) Faces Places +

    +
    +
    + +
    +
    +

    + The unusual documentary Faces Places (in French, Visages Villages) turns on the friendship between the accomplished street artist JR and legendary film director Agnès Varda, whose work was central to the development of the French New Wave movement. The pair (whose difference in age is 55 years) met after years of admiring each other’s work and decided to create a documentary portrait of France — by making a number of actual portraits. The film chronicles a leg of the "Inside Outside Project," a roving art initiative in which JR makes enormous portraits of people he meets and pastes them onto buildings and walls. In the film, Varda joins him, and as they talk to people around the country, they grow in their understanding of themselves and of each other. The development of their friendship, which is both affectionate and mutually sharpening, forms Faces Places’ emotional center. +

    +

    + Faces Places is currently streaming on Netflix and available to digitally rent on Google Play and YouTube. +

    + +

    + 19) Ingrid Goes West +

    +
    +
    + +
    +
    +

    + Ingrid Goes West is a twisted and dark comedy — part addiction narrative, part stalker story — and yet it’s set in a world that’s almost pathologically cheery: the glossy, sunny, nourishing, superfood- and superlative-loving universe of Instagram celebrity. But despite Ingrid Goes West’s spot-on take on that world, the best thing about the film is that it refuses to traffic in lazy buzzwords and easy skewering, particularly at the expense of young women. Instead, the movie conveys that behind every Instagram image and meltdown is a real person, with real insecurities, real feelings, and real problems. And it recognizes that living a life performed in public can be its own kind of self-deluding prison. +

    +

    + Ingrid Goes West is currently streaming on Hulu and available to digitally rent on YouTube and Google Play. +

    +

    + 18) Lady Macbeth +

    +
    +
    + +
    +
    +

    + Lady Macbeth is no placid costume drama. Adapted from an 1865 Russian novella by Nikolai Leskov, the movie follows Katherine (the astounding Florence Pugh), a woman in the Lady Macbeth line characterized by a potent cocktail of very few scruples and a lot of determination. She's a chilling avatar for the ways that class and privilege — both obvious and hidden — insulate some people from the consequences of their actions while damning others. Lady Macbeth is also a dazzling directorial debut from William Oldroyd, a thrilling combination of sex, murder, intrigue, and power plays. It’s visually stunning, each frame composed so carefully and deliberately that the wildness and danger roiling just below the surface feels even more frightening. Each scene ratchets up the tension to an explosive, chilling end. +

    +

    + Lady Macbeth is currently streaming on HBO Go and HBO Now, and it is available to digitally rent on Amazon Prime, Vudu, YouTube, iTunes, and Google Play. +

    +

    + 17) BPM (Beats Per Minute) +

    +
    +
    + +
    +
    +

    + BPM (Beats Per Minute) is a remarkably tender and stirring story of the Paris chapter of ACT UP, an AIDS activism group, and the young people who found themselves caught in the crosshairs of the AIDS crisis in the early 1990s. The film follows both the group's actions and the individual members’ shifting relationships to one another — enemies becoming friends, friends becoming lovers, lovers becoming caretakers — as well as their struggles with the disease wracking their community. As an account of the period, it’s riveting; as an exploration of life and love set at the urgent intersection of the political and the personal, it’s devastating. +

    +

    + BPM (Beats Per Minute) is currently streaming on Hulu and available to digitally rent on Google Play and YouTube. +

    +

    + 16) The Big Sick +

    +
    +
    + +
    +
    +

    + Few 2017 movies could top the charm and tenderness of The Big Sick, which hits all the right romantic comedy notes with one unusual distinction: It feels like real life. That’s probably because The Big Sick is written by real-life married couple Emily V. Gordon and Silicon Valley's Kumail Nanjiani, and based on their real-life romance. The Big Sick — which stars Nanjiani as a version of himself, alongside Zoe Kazan as Emily — is funny and sweet while not backing away from matters that romantic comedies don’t usually touch on, like serious illness, struggles in long-term marriages, and religion. As it tells the couple’s story, which takes a serious turn when Emily falls ill with a mysterious infection and her parents (played by Holly Hunter and Ray Romano) come to town, it becomes a funny and wise story about real love. +

    +

    + The Big Sick is currently streaming on Amazon Prime and available to digitally rent on iTunes, Vudu, Amazon, YouTube, and Google Play. +

    +

    + 15) Mother! +

    +
    +
    + +
    +
    +

    + There’s so much pulsing beneath the surface of Mother! that it’s hard to grab on to just one theme as what it “means.” It’s full-on apocalyptic fiction, and like all stories of apocalypse, it’s intended to draw back the veil on reality and show us what’s really beneath. And this movie gets wild: If its gleeful cracking apart of traditional theologies doesn’t get you (there’s a lot of Catholic folk imagery here, complete with an Ash Wednesday-like mud smearing on the foreheads of the faithful), its bonkers scenes of chaos probably will. Mother! is a movie designed to provoke fury, ecstasy, madness, catharsis, and more than a little awe. Watching it, and then participating in the flurry of arguments and discussions unpacking it, was among my best moviegoing experiences of 2017. +

    +

    + Mother! is available to digitally purchase on Google Play and YouTube. +

    +

    + 14) A Ghost Story +

    +
    +
    + +
    +
    +

    + Director David Lowery filmed A Ghost Story in secret, then premiered it at the Sundance Film Festival to critical acclaim. The movie starts out being about a grieving widow (Rooney Mara) trying to live through the pain of losing her beloved husband, but it soon shifts focus to the ghost of her husband (Casey Affleck, covered in a sheet), evolving into a compelling rumination on the nature of time, memory, history, and the universe. Bathed in warm humor and wistful longing, it's a film that stays with you long after it’s over, a lingering reminder of the inextricable link between love and place. +

    +

    + A Ghost Story is available to digitally rent on iTunes, Vudu, Amazon, Google Play, and YouTube. +

    +

    + 13) The Square +

    +
    +
    + +
    +
    + +

    + The Square is currently streaming on Hulu and available to digitally rent on Google Play and YouTube. +

    +

    + 12) Dunkirk +

    +
    +
    + +
    +
    +

    + Dunkirk, a true cinematic achievement from acclaimed director Christopher Nolan, backs off conventional notions of narrative and chronology as much as possible, while leaning headfirst into everything else that makes a movie a visceral work of art aimed at the senses: the images, the sounds, the scale, the swelling vibrations of it all. You can’t smell the sea spray, but your brain may trick you into thinking you can. Nolan’s camera pushes the edges of the screen as far as it can as Dunkirk engulfs the audience in something that feels like a lot more than a war movie. It’s a symphony for the brave and broken, and it resolves in a major key — but one with an undercurrent of sorrow, and of sober warning. Courage in the face of danger is not just for characters in movies. +

    +

    + Dunkirk is currently streaming on HBO Go and HBO Now, and available to digitally rent on Google Play and YouTube. +

    +

    + 11) Rat Film +

    +
    +
    + +
    +
    +

    + Rat Film is about rats, yes — and rat poison experts and rat hunters and people who keep rats as pets. But it’s also about the history of eugenics, dubious science, “redlining,” and segregated housing in Baltimore. All these pieces come together to form one big essay, where the meaning of each vignette only becomes clearer in light of the whole. It’s a fast-paced, no-holds-barred exploration of a damning history, and it accrues meaning as the images, sounds, and text pile up. +

    +

    + Rat Film is available to digitally rent on YouTube and Google Play. +

    +

    + 10) A Quiet Passion +

    +
    +
    + +
    +
    +

    + A Quiet Passion is technically a biographical film about Emily Dickinson, but it transcends its genre to become something more like poetry. It’s a perplexing and challenging film, crafted without the traditional guardrails that guide most biographical movies — dates, times, major accomplishments, and so on. Time slips away in the film almost imperceptibly, and the narrative arc doesn’t yield easily to the viewer. Cynthia Nixon plays Emily Dickinson, whose poetry and life is a perfect match for the signature style of director Terence Davies: rich in detail, deeply enigmatic, and weighed down with a kind of sparkling, joy-tinged sorrow. A Quiet Passion is a portrait, both visual and narrative, of the kind of saint most modern people can understand: one who is certain of her uncertainty, and yearning to walk the path on which her passion and longing meet. +

    +

    + A Quiet Passion is currently streaming on Amazon Prime and available to digitally rent or purchase on iTunes, Vudu, Amazon, YouTube, and Google Play. +

    +

    + 9) Columbus +

    +
    +
    + +
    +
    +

    + Columbus is a stunner of a debut from video essayist turned director Kogonada. Haley Lu Richardson stars as Casey, a young woman living in Columbus, Indiana, who cares for her mother, works at a library, and harbors a passion for architecture. (Columbus is a mecca for modernist architecture scholars and enthusiasts.) When a visiting architecture scholar falls into a coma in Columbus, his estranged son Jin (John Cho) arrives to wait for him and strikes up a friendship with Casey, who starts to show him her favorite buildings. The two begin to unlock something in each other that’s hard to define but life-changing for both. Columbus is beautiful and subtle, letting us feel how the places we build and the people we let near us move and mold us. +

    +

    + Columbus is currently streaming on Hulu and available to rent on Google Play and YouTube. +

    +

    + 8) The Florida Project +

    +
    +
    + +
    +
    +

    + Sean Baker’s The Florida Project unfolds at first like a series of sketches about the characters who live in a purple-painted, $35-a-night motel called the Magic Castle down the street from Disney World. The film is held together by the hysterical antics of a kid named Moonee and her pack of young friends, as well as long-suffering hotel manager Bobby (a splendid, warm Willem Dafoe), who tries to put up with it all while keeping some kind of order. But as The Florida Project goes on, a narrative starts to form, one that chronicles with heartbreaking attention the sort of dilemmas that face poor parents and their children in America, and the broken systems that try to cope with impossible situations. +

    +

    + The Florida Project is currently streaming on Amazon Prime and available to digitally rent on YouTube, Vudu, and Google Play. +

    +

    + 7) Call Me by Your Name +

    +
    +
    + +
    +
    +

    + Luca Guadagnino’s gorgeous film Call Me by Your Name adapts André Aciman’s 2007 novel about a precocious 17-year-old named Elio (Timothée Chalamet), who falls in lust and love with his father’s 24-year-old graduate student Oliver (Armie Hammer). It’s remarkable for how it turns literature into pure cinema, all emotion and image and heady sensation. Set in 1983 in Northern Italy, Call Me by Your Name is less about coming out than coming of age, but it also captures a particular sort of love that’s equal parts passion and torment, a kind of irrational heart fire that opens a gate into something longer-lasting. The film is a lush, heady experience for the body, but it’s also an arousal for the soul. +

    +

    + Call Me By Your Name is available to digitally purchase on Amazon, YouTube, and Google Play. +

    +

    + 6) Personal Shopper +

    +
    +
    + +
    +
    +

    + In her second collaboration with French director Olivier Assayas, Kristen Stewart plays a personal shopper to a wealthy socialite, with a sideline as an amateur ghost hunter who’s searching for her dead twin brother. Personal Shopper is deeper than it seems at first blush, a meditation on grief and an exploration of “between” places — on the fringes of wealth, and in the space between life and death. Some souls are linked in a way that can’t be shaken, and whether or not there’s an afterlife doesn’t change the fact that we see and sense them everywhere. (Personal Shopper also has one of the most tense extended scenes involving text messaging ever seen onscreen.) +

    +

    + Personal Shopper is currently streaming on Showtime and available to rent on Vudu, YouTube, Amazon, iTunes, and Google Play. +

    +

    + 5) Princess Cyd +

    +
    +
    + +
    +
    +

    + Stephen Cone is a master of small, carefully realized filmmaking; his earlier films such as The Wise Kids and Henry Gamble’s Birthday Party combine an unusual level of empathy for his characters with an unusual combination of interests: love, desire, sexual awakenings, and religion. Princess Cyd is his most accomplished film yet, about a young woman named Cyd (Jessie Pinnick) who finds herself attracted to Katie (Malic White), a barista, while visiting her Aunt Miranda (Rebecca Spence, playing a character modeled on the author Marilynne Robinson) in Chicago. As she works through her own sexual awakening with Katie, Cyd unwinds some of the ways Miranda’s life has gotten too safe. They provoke each other while forming a bond and being prodded toward a bigger understanding of the world. It is a graceful and honest film, and it feels like a modest miracle. +

    +

    + Princess Cyd is currently streaming on Netflix and available to digitally rent on Google Play and YouTube. +

    +

    + 4) Get Out +

    +
    +
    + +
    +
    +

    + Racism is sinister, frightening, and deadly. But Get Out (a stunning directorial debut from Key & Peele's Jordan Peele) isn’t about the blatantly, obviously scary kind of racism — burning crosses and lynchings and snarling hate. Instead, it’s interested in showing how the parts of racism that try to be aggressively unscary are just as horrifying, and it’s interested in making us feel that horror in a visceral, bodily way. In the tradition of the best classic social thrillers, Get Out takes a topic that is often approached cerebrally — casual racism — and turns it into something you feel in your tummy. And it does it with a wicked sense of humor. +

    +

    + Get Out is currently streaming on HBO Go and HBO Now, and is available to digitally rent on iTunes, Amazon, Google Play, YouTube, and Vudu. +

    +

    + 3) The Work +

    +
    +
    + +
    +
    +

    + The Work is an outstanding, astonishing accomplishment and a viewing experience that will leave you shaken (but in a good way). At Folsom Prison in California, incarcerated men regularly participate in group therapy, and each year other men from the “outside” apply to participate in an intense four-day period of group therapy alongside Folsom’s inmates. The Work spends almost all of its time inside the room where that therapy happens, observing the strong, visceral, and sometimes violent emotions the men feel as they expose the hurt and raw nerves that have shaped how they encounter the world. Watching is not always easy, but by letting us peek in, the film invites viewers to become part of the experience — as if we, too, are being asked to let go. +

    +

    + The Work is streaming on Topic.com and available to digitally rent on Google Play and YouTube. +

    +

    + 2) Ex Libris +

    +
    +
    + +
    +
    +

    + Frederick Wiseman is one of the towering giants of nonfiction film, a keen observer of American institutions — ranging from prisons to dance companies to welfare offices — for the past half-century. Ex Libris is his mesmerizing look at the New York Public Library and the many functions it fills, which go far beyond housing books. Wiseman works in the observational mode, which means his films contain no captions, dates, or talking-head interviews: We just see what his camera captured, which in this case includes community meetings, benefit dinners, after-school programs, readings with authors and scholars (including Richard Dawkins and Ta-Nehisi Coates), and NYPL patrons going about their business in the library’s branches all over the city. The result is almost hypnotic and, perhaps surprisingly, deeply moving. It makes a case for having faith in the public institutions where ordinary people work — away from the limelight, without trying to score political points — in order to make our communities truly better. +

    +

    + Ex Libris will air on PBS in the fall and then be available to cardholders in many library systems across the country via Kanopy. +

    +

    + 1) Lady Bird +

    +
    +
    + +
    +
    +

    + Lady Bird topped my list almost instantly, and only rose in my estimation on repeated viewings. For many who saw it (including me), it felt like a movie made not just for but about me. Lady Bird is a masterful, exquisite coming-of-age comedy starring the great Saoirse Ronan as Christine — or “Lady Bird,” as she’s re-christened herself — and it’s as funny, smart, and filled with yearning as its heroine. Writer-director Greta Gerwig made the film as an act of love, not just toward her hometown of Sacramento but also toward girlhood, and toward the feeling of always being on the outside of wherever real life is happening. Lady Bird is the rare movie that manages to be affectionate, entertaining, hilarious, witty, and confident. And one line from it struck me as the guiding principle of many of the year’s best films: “Don’t you think they are the same thing? Love, and attention?” +

    +

    + Lady Bird is currently streaming on Amazon Prime and available to digitally rent on Amazon, Google Play, and YouTube. +

    +

    + Honorable mentions: Marjorie Prime, Phantom Thread, Casting JonBenet, The Post, The Shape of Water, Logan Lucky, I, Tonya, The Lost City of Z, Graduation, Spettacolo, Loveless, Restless Creature: Wendy Whelan, In Transit, The Reagan Show +

    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    + + +
    + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected-images.json new file mode 100644 index 000000000..d572c8db2 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected-images.json @@ -0,0 +1,3 @@ +[ + "https:\/\/medias.liberation.fr\/photo\/1075029-screenshot-alphonse-vape-wave-6-days.jpg?modified_at=1511536242&picto=fb&ratio_x=191&ratio_y=100&width=600" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected-metadata.json new file mode 100644 index 000000000..00c0019ac --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Alexandre Hervaud, J\u00e9r\u00e9my Piette", + "Direction": null, + "Excerpt": "S\u00e9ries, documentaires, programmes jeunesse\u2026 Retrouvez les recommandations de\u00a0Lib\u00e9ration\u00a0pour savoir quoi regarder sur vos \u00e9crans cette semaine.\nPour d\u00e9passer...", + "Image": "https:\/\/medias.liberation.fr\/photo\/1075029-screenshot-alphonse-vape-wave-6-days.jpg?modified_at=1511536242&picto=fb&ratio_x=191&ratio_y=100&width=600", + "Title": "Screenshot\u00a0: \u00abVape Wave\u00bb, \u00ab6\u00a0Days\u00bb, \u00abAlphonse Pr\u00e9sident\u00bb\u2026", + "SiteName": "Lib\u00e9ration" +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected.html new file mode 100644 index 000000000..77e6011d2 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/expected.html @@ -0,0 +1,107 @@ +
    +

    + Séries, documentaires, programmes jeunesse… Retrouvez les recommandations de Libération pour savoir quoi regarder sur vos écrans cette semaine. +

    +

    + Pour dépasser le tabac +

    +

    + Vape Wave (documentaire, 1h28, Planète+) +

    +

    + +

    +

    + Pendant quelques jours, le doute a plané : l’Etat comptait-il vraiment légiférer contre la cigarette dans les films français, que ce soit via une interdiction pure et simple ou via un système de «punition» (coupe des aides CNC, par exemple) pour les longs-métrages qui sentent le mégot ? Si le rétropédalage de la ministre Buzyn n’en est pas vraiment un (elle n’avait jamais clairement menacé le septième art), la polémique a le mérite de pointer la (sur)représentation clopesque sur écran. Et si, comme c’est le cas dans la vie quotidienne, on voyait progressivement les cigarettes électroniques remplacer les tiges nicotinées authentiques ? Que ceux qui mettraient en doute le potentiel cinématographique des vapoteuses se ruent sur Vape Wave, documentaire militant signé Jan Kounen, ex-fumeur reconverti à la vape dont les images magnifient les volutes de vapeur recrachée. +

    +

    + Si le film du réalisateur de Dobermann et 99 Francs part un peu dans tous les sens, il a le mérite de défendre avec une passion contagieuse ce qui semble, de loin, être le meilleur et plus sain substitut à la clope, n’en déplaise aux mesures restrictives imposées en France à son égard. Financé en partie via crowdfunding, le documentaire a été présenté par Kounen à travers toute la France lors de projection tenant quasiment de l’évangélisation. Disponible en VOD/DVD, il a été diffusé cette semaine sur la chaîne Planète+, qui le rediffusera les 25/11, 30/11 et 02/12 prochains. (Alexandre Hervaud) +

    +

    + Pour écouter parler un génie +

    +

    + Dans la tête d’Alan Moore (websérie documentaire, 8x5min, Arte Creative) +

    +

    + +

    +

    + Le week-end dernier, Libération publiait un portrait de der consacré à l’auteur britannique Alan Moore, connu pour ses BD cultes (V pour Vendetta, Watchmen, From Hell), à l’occasion de la sortie de son deuxième roman, le pavé Jérusalem. En attendant l’imminente sortie d’une version longue de son entretien avec Libé, on pourra se replonger dans les épisodes d’une websérie documentaire d’Arte Creative en 8 épisodes consacré au maître. Brexit, magie, Anonymous font partie des sujets discutés avec le maître au fil de ce programme sobrement intitulé Dans la tête d’Alan Moore. (A.H.) +

    +

    + Pour honorer la mémoire d’une icône queer +

    +

    + The Death and Life of Marsha P. Johnson (docu, 1h45, Netflix) +

    +

    + +

    +

    + Marsha, la «Rosa Parks du mouvement LGBTQ». Marsha «la prostituée, l’actrice et la sainte, modèle d’Andy Warhol» ou encore Marsha l’élaborée, la radicale, «avec ses plumes et ce maquillage qu’elle ne mettait jamais bien». «Queen Marsha» a été retrouvée morte dans l’Hudson en juillet 1992, alors qu’on la voyait encore parader dans les rues de Greenwich Village quelques jours auparavant. Un choc glaçant. Là où son corps a été repêché puis ingratement déposé, les sans-abri ont constitué le lendemain un mémorial de bouteilles et de plantes qui délimitent les contours de l’absente. +

    +

    + Marsha P. Johnson de son nom complet, icône queer, femme transgenre noire américaine et emblème de la lutte pour les droits des LGBTQ avait été l’une des premières à s’engager lors des émeutes de Stonewall à New York, en 1969 : «C’est la révolution. Dieu merci.» Marsha était une fleur souriante au parfum d’espoir. Le documentaire The Death and Life of Marsha P. Johnson du cinéaste David France relate l’enquête de l’activiste Victoria Cruz, membre de l’organisation Anti-Violence Project à New York qui, avant de prendre sa retraite, réclame que lumière soit faite sur la disparition de l’icône […] Lire la suite de la critique de Jérémy Piette sur Libération.fr +

    +

    + Pour Michel Vuilermoz (et rien d’autre) +

    +

    + Alphonse President (série, 10x26, OCS Max) +

    +

    + +

    +

    + Un temps baptisée French Touch, la série Alphonse Président est le dernier né des programmes originaux made in OCS. On savait les budgets de la chaîne bien moins généreux que ceux de Canal+ (voire que ceux de France 3 Limousin), et cette série le prouve à nouveau régulièrement, notamment lors d’une scène de conférence de presse alternant plans larges d’une authentique conf' à l’Elysée période François Hollande et plans serrés d’acteurs filmés dans un château des Pays de la Loire où a eu lieu le tournage. Le principal atout (et quel atout) de cette série écrite et réalisée par Nicolas Castro (Des lendemains qui chantent, 2014) réside dans son interprète principal, Michel Vuillermoz. +

    +

    + Dans le rôle d’un sénateur ringard devenu par un concours de circonstances président de la République, ce pensionnaire de la Comédie-Française et complice d’Albert Dupontel fait des merveilles, notamment lorsque le scénario lui prête des répliques enflammées typiques de la langue de bois politicienne – pas étonnant qu’il brasse du vent, son personnage de prof d’histoire retraité s’appelle Alphonse Dumoulin. C’est lorsqu’il n’est plus à l’écran que les choses se gâtent : si Jean-Michel Lahmi (de la bande d’Edouard Baer) fait le job en grand patron des flics, difficile de croire une seconde à Nabiha Akkari dans le rôle de la Première ministre – et pas uniquement parce que l’idée d’avoir une femme trentenaire issue de la diversité à Matignon sonne hélas comme un doux rêve en 2017. Si, en matière de fiction politique sérieuse, un Baron Noir n’a pas grand-chose à envier à un House of Cards, côté comique la France est encore loin d’avoir son Veep. Gageons que la génération LREM saura largement inspirer des scénaristes moqueurs. (A.H.) +

    +

    + Pour les coulisses d’un tournage dément +

    +

    + Jim & Andy (documentaire, 1h33, Netflix)  +

    +

    + +

    +

    + A la sortie de Man on the Moon (2000), le magnifique film de Milos Forman consacré à Andy Kaufman – comique et génie de la performance absurde mort en 1984 –, le cinéaste et les acteurs insistaient dans chaque interview sur l’in­croyable comportement de Jim Carrey pendant le tournage : il aurait été comme possédé par Kaufman, se prenant pour lui 24 heures sur 24. Certains affirmaient même ne jamais avoir eu l’impression que l’acteur était présent, tant son modèle avait littéralement pris sa place. Nous en avons aujourd’hui la preuve en images car tout cela avait été filmé par Bob Zmuda et Lynne Margulies, l’ancien complice et la veuve de Kaufman. +

    +

    + Dans le passionnant Jim & Andy : the Great Beyond, disponible sur Netflix, Chris Smith a monté ces documents inédits parallèlement à un entretien dans lequel Jim Carrey revient sur cette expérience unique. Lire la suite de la critique de Marcos Uzal sur Liberation.fr +

    +

    + Pour un trip sibérien en totale autarcie +

    +

    + Braguino (documentaire, 50min, Arte) +

    +

    + +

    +

    + La querelle peut se trouver derrière toutes les portes, y compris celle de l’exil. On a beau croire avoir tourné le dos à tout, à cette inclination humaine à nourrir sa propre haine, l’allergie peut regermer fissa sur une peau qui frissonne à l’approche de ce voisin que l’on ne comprend pas. Issu d’une lignée de vieux-croyants orthodoxes russes, Sacha Braguine a pris sa famille sous le bras, loin de toute autre présence humaine en taïga sibérienne. Un autre groupe, les Kiline, a décidé d’en faire de même et de s’installer de l’autre côté de la rivière. Qui est arrivé en premier ? Qui menace l’autre ? L’histoire de l’impossible communauté peut commencer. +

    +

    + La lecture d’Ermites dans la taïga (1992) de Vassili Peskov, authentique récit sur la famille Lykov opérant une migration similaire en 1938, a poussé l’artiste Clément Cogitore à rencontrer les Braguine, puis à se faire témoin de la bisbille de voisinage en 2016. Il en est revenu avec un nouveau film d’une cinquantaine de minutes : Braguino, soutenu par le prix Le Bal de la jeune création avec l’ADAGP. Le documentaire y frôle son déguisement fictionnel, tant ce qui s’y déroule convoque une dramaturgie comme invoquée par on ne sait quel rituel vaudou […] Lire la suite de la critique de Jérémy Piette sur Liberation.fr, le film diffusé cette semaine sur Arte est visible en intégralité ci-dessus. +

    +

    + Pour un thriller tiré de faits réels +

    +

    + 6 Days (film, 1h34, Netflix) +

    +

    + +

    +

    + Fin avril 1980, l’ambassade d’Iran à Londres a été le théâtre d’une prise d’otages largement médiatisée : une trentaine de personnes ont ainsi été retenues pendant six jours par des soldats iraniens dissidents exigeant la libération de 91 prisonniers. Avec Margaret Thatcher au 10 Downing Street à l’époque, pas question pour l’Angleterre d’avoir l’air mou du genou sur la réponse à apporter à cette crise scrutée par les caméras du monde entier. Le SAS (Special Air Service) est sur le coup : l’opération Nimrod se met en place pour prendre d’assaut l’ambassade. +

    +

    + Inspiré par cet épisode, 6 Days de Toa Fraser (The Dead Lands, 2014) est un thriller carré pouvant compter sur l'autorité naturelle de Mark Strong (Kingsman) ici recyclé en flic londonien et sur la néo-badass attitude de Jamie Bell, bien loin du freluquet danseur de Billy Elliot puisqu'on le retrouve ici en soldat chargé d’organiser l’opération de secours. Attention, la bande-annonce ci-dessus dévoile à peu près l’intégralité des scènes d’action du film. (A.H.) +

    Alexandre Hervaud , Jérémy Piette +

    \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/source.html new file mode 100644 index 000000000..5cfc0ba14 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/videos-2/source.html @@ -0,0 +1,2043 @@ + + + + + Screenshot : «Vape Wave», «6 Days», «Alphonse Président»… - Culture / Next + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Search + + + + + + + + + Direct + + + + + + User + + + + + + + + + 100 + + + + + + + + Zoom + + + + + + Quiz + + + ? + + + + + + Libération Diamond + + + + + + clock + + + + + + + + + xml + + + + + + netvibes + + + + + + + + live + + + + + + anciens-numeros + + + + + + + + data + + + + + + + + + desintox + + + + + + + + + + + + + + + diapo + + + + + + + + edito + + + + + + + + + election-2017 + + + + + + + + + + + election + + + + + + + + essentiel + + + + + + + + generique + + + + + + idee + + + + + + + + + + + + + + + jo + + + + + + + + + + + + next + + + + + + + + portrait + + + + + + + + + + radio + + + + + + + + + + + son + + + + + + + + + alerte + + + + + + top-100 + + + + + + + + + star + + + + + + une + + + + + + + video + + + + + + + scroll + + + + + + + politiques + + + + + + + + + + + + + + + + food + + + + + + + + + + + + sciences + + + + + + + + + + + + Facebook + + + + + + Whatsapp + + + + + + + + Twitter + + + + + + insta + + + + + + vine + + + + + + later + + + + + + + + glass + + + + + + Mail + + + + + + print + + + + + + Facebook + + + + + + Instagram + + + + + + Twitter + + + + + + Calendar + + + + + + download + + + + + + cross + + + + + + zoom-in + + + + + + + + + zoom-out + + + + + + + + + previous + + + + + + + + + next + + + + + + + + + truck + + + + + + + + + + + visa + + + + + + + + + mastercard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user-libe + + + + + + user-doc + + + + + + user-doc-list + + + + + + + + + user-mail + + + + + + + user-security + + + + + + user-settings + + + + + + user-shop + + + + + + + + + user-star + + + + + + + Ruban abo + + + + + + Losange orange + + + + + + List check + + + + + + Most read + + + + + + Ptit Libé + + + + + + + sport + + + + + + + + + blog + + + + + + + + voyage + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    + +
    + + + + +
    + +
    +
    +
    +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + Sur vos écrans cette semaine +
      +

      + Screenshot : «Vape Wave», «6 Days», «Alphonse Président»… +

      +
      + Par Alexandre Hervaud et Jérémy Piette +
      +
      +
      +
      +
      +
      +
      + «Vape Wave», «6 Days», «Alphonse président» et «Braguino» + +
      + «Vape Wave», «6 Days», «Alphonse président» et «Braguino» DR + +
      +
      +
      +

      + Séries, documentaires, programmes jeunesse… Retrouvez les recommandations de Libération pour savoir quoi regarder sur vos écrans cette semaine. +

      +

      + Pour dépasser le tabac +

      +

      + Vape Wave (documentaire, 1h28, Planète+) +

      +

      + +

      +

      + Pendant quelques jours, le doute a plané : l’Etat comptait-il vraiment légiférer contre la cigarette dans les films français, que ce soit via une interdiction pure et simple ou via un système de «punition» (coupe des aides CNC, par exemple) pour les longs-métrages qui sentent le mégot ? Si le rétropédalage de la ministre Buzyn n’en est pas vraiment un (elle n’avait jamais clairement menacé le septième art), la polémique a le mérite de pointer la (sur)représentation clopesque sur écran. Et si, comme c’est le cas dans la vie quotidienne, on voyait progressivement les cigarettes électroniques remplacer les tiges nicotinées authentiques ? Que ceux qui mettraient en doute le potentiel cinématographique des vapoteuses se ruent sur Vape Wave, documentaire militant signé Jan Kounen, ex-fumeur reconverti à la vape dont les images magnifient les volutes de vapeur recrachée. +

      +

      + Si le film du réalisateur de Dobermann et 99 Francs part un peu dans tous les sens, il a le mérite de défendre avec une passion contagieuse ce qui semble, de loin, être le meilleur et plus sain substitut à la clope, n’en déplaise aux mesures restrictives imposées en France à son égard. Financé en partie via crowdfunding, le documentaire a été présenté par Kounen à travers toute la France lors de projection tenant quasiment de l’évangélisation. Disponible en VOD/DVD, il a été diffusé cette semaine sur la chaîne Planète+, qui le rediffusera les 25/11, 30/11 et 02/12 prochains. (Alexandre Hervaud) +

      +

      + Pour écouter parler un génie +

      +

      + Dans la tête d’Alan Moore (websérie documentaire, 8x5min, Arte Creative) +

      +

      + +

      +

      + Le week-end dernier, Libération publiait un portrait de der consacré à l’auteur britannique Alan Moore, connu pour ses BD cultes (V pour Vendetta, Watchmen, From Hell), à l’occasion de la sortie de son deuxième roman, le pavé Jérusalem. En attendant l’imminente sortie d’une version longue de son entretien avec Libé, on pourra se replonger dans les épisodes d’une websérie documentaire d’Arte Creative en 8 épisodes consacré au maître. Brexit, magie, Anonymous font partie des sujets discutés avec le maître au fil de ce programme sobrement intitulé Dans la tête d’Alan Moore. (A.H.) +

      +

      + Pour honorer la mémoire d’une icône queer +

      +

      + The Death and Life of Marsha P. Johnson (docu, 1h45, Netflix) +

      +

      + +

      +

      + Marsha, la «Rosa Parks du mouvement LGBTQ». Marsha «la prostituée, l’actrice et la sainte, modèle d’Andy Warhol» ou encore Marsha l’élaborée, la radicale, «avec ses plumes et ce maquillage qu’elle ne mettait jamais bien». «Queen Marsha» a été retrouvée morte dans l’Hudson en juillet 1992, alors qu’on la voyait encore parader dans les rues de Greenwich Village quelques jours auparavant. Un choc glaçant. Là où son corps a été repêché puis ingratement déposé, les sans-abri ont constitué le lendemain un mémorial de bouteilles et de plantes qui délimitent les contours de l’absente. +

      +

      + Marsha P. Johnson de son nom complet, icône queer, femme transgenre noire américaine et emblème de la lutte pour les droits des LGBTQ avait été l’une des premières à s’engager lors des émeutes de Stonewall à New York, en 1969 : «C’est la révolution. Dieu merci.» Marsha était une fleur souriante au parfum d’espoir. Le documentaire The Death and Life of Marsha P. Johnson du cinéaste David France relate l’enquête de l’activiste Victoria Cruz, membre de l’organisation Anti-Violence Project à New York qui, avant de prendre sa retraite, réclame que lumière soit faite sur la disparition de l’icône […] Lire la suite de la critique de Jérémy Piette sur Libération.fr +

      +

      + Pour Michel Vuilermoz (et rien d’autre) +

      +

      + Alphonse President (série, 10x26, OCS Max) +

      +

      + +

      +

      + Un temps baptisée French Touch, la série Alphonse Président est le dernier né des programmes originaux made in OCS. On savait les budgets de la chaîne bien moins généreux que ceux de Canal+ (voire que ceux de France 3 Limousin), et cette série le prouve à nouveau régulièrement, notamment lors d’une scène de conférence de presse alternant plans larges d’une authentique conf' à l’Elysée période François Hollande et plans serrés d’acteurs filmés dans un château des Pays de la Loire où a eu lieu le tournage. Le principal atout (et quel atout) de cette série écrite et réalisée par Nicolas Castro (Des lendemains qui chantent, 2014) réside dans son interprète principal, Michel Vuillermoz. +

      +

      + Dans le rôle d’un sénateur ringard devenu par un concours de circonstances président de la République, ce pensionnaire de la Comédie-Française et complice d’Albert Dupontel fait des merveilles, notamment lorsque le scénario lui prête des répliques enflammées typiques de la langue de bois politicienne – pas étonnant qu’il brasse du vent, son personnage de prof d’histoire retraité s’appelle Alphonse Dumoulin. C’est lorsqu’il n’est plus à l’écran que les choses se gâtent : si Jean-Michel Lahmi (de la bande d’Edouard Baer) fait le job en grand patron des flics, difficile de croire une seconde à Nabiha Akkari dans le rôle de la Première ministre – et pas uniquement parce que l’idée d’avoir une femme trentenaire issue de la diversité à Matignon sonne hélas comme un doux rêve en 2017. Si, en matière de fiction politique sérieuse, un Baron Noir n’a pas grand-chose à envier à un House of Cards, côté comique la France est encore loin d’avoir son Veep. Gageons que la génération LREM saura largement inspirer des scénaristes moqueurs. (A.H.) +

      +

      + Pour les coulisses d’un tournage dément +

      +

      + Jim & Andy (documentaire, 1h33, Netflix)  +

      +

      + +

      +

      + A la sortie de Man on the Moon (2000), le magnifique film de Milos Forman consacré à Andy Kaufman – comique et génie de la performance absurde mort en 1984 –, le cinéaste et les acteurs insistaient dans chaque interview sur l’in­croyable comportement de Jim Carrey pendant le tournage : il aurait été comme possédé par Kaufman, se prenant pour lui 24 heures sur 24. Certains affirmaient même ne jamais avoir eu l’impression que l’acteur était présent, tant son modèle avait littéralement pris sa place. Nous en avons aujourd’hui la preuve en images car tout cela avait été filmé par Bob Zmuda et Lynne Margulies, l’ancien complice et la veuve de Kaufman. +

      +

      + Dans le passionnant Jim & Andy : the Great Beyond, disponible sur Netflix, Chris Smith a monté ces documents inédits parallèlement à un entretien dans lequel Jim Carrey revient sur cette expérience unique. Lire la suite de la critique de Marcos Uzal sur Liberation.fr +

      +

      + Pour un trip sibérien en totale autarcie +

      +

      + Braguino (documentaire, 50min, Arte) +

      +

      + +

      +

      + La querelle peut se trouver derrière toutes les portes, y compris celle de l’exil. On a beau croire avoir tourné le dos à tout, à cette inclination humaine à nourrir sa propre haine, l’allergie peut regermer fissa sur une peau qui frissonne à l’approche de ce voisin que l’on ne comprend pas. Issu d’une lignée de vieux-croyants orthodoxes russes, Sacha Braguine a pris sa famille sous le bras, loin de toute autre présence humaine en taïga sibérienne. Un autre groupe, les Kiline, a décidé d’en faire de même et de s’installer de l’autre côté de la rivière. Qui est arrivé en premier ? Qui menace l’autre ? L’histoire de l’impossible communauté peut commencer. +

      +

      + La lecture d’Ermites dans la taïga (1992) de Vassili Peskov, authentique récit sur la famille Lykov opérant une migration similaire en 1938, a poussé l’artiste Clément Cogitore à rencontrer les Braguine, puis à se faire témoin de la bisbille de voisinage en 2016. Il en est revenu avec un nouveau film d’une cinquantaine de minutes : Braguino, soutenu par le prix Le Bal de la jeune création avec l’ADAGP. Le documentaire y frôle son déguisement fictionnel, tant ce qui s’y déroule convoque une dramaturgie comme invoquée par on ne sait quel rituel vaudou […] Lire la suite de la critique de Jérémy Piette sur Liberation.fr, le film diffusé cette semaine sur Arte est visible en intégralité ci-dessus. +

      +

      + Pour un thriller tiré de faits réels +

      +

      + 6 Days (film, 1h34, Netflix) +

      +

      + +

      +

      + Fin avril 1980, l’ambassade d’Iran à Londres a été le théâtre d’une prise d’otages largement médiatisée : une trentaine de personnes ont ainsi été retenues pendant six jours par des soldats iraniens dissidents exigeant la libération de 91 prisonniers. Avec Margaret Thatcher au 10 Downing Street à l’époque, pas question pour l’Angleterre d’avoir l’air mou du genou sur la réponse à apporter à cette crise scrutée par les caméras du monde entier. Le SAS (Special Air Service) est sur le coup : l’opération Nimrod se met en place pour prendre d’assaut l’ambassade. +

      +

      + Inspiré par cet épisode, 6 Days de Toa Fraser (The Dead Lands, 2014) est un thriller carré pouvant compter sur l'autorité naturelle de Mark Strong (Kingsman) ici recyclé en flic londonien et sur la néo-badass attitude de Jamie Bell, bien loin du freluquet danseur de Billy Elliot puisqu'on le retrouve ici en soldat chargé d’organiser l’opération de secours. Attention, la bande-annonce ci-dessus dévoile à peu près l’intégralité des scènes d’action du film. (A.H.) +

      Alexandre Hervaud , Jérémy Piette +
      +
      + +
      +
      +
      +
      +
      + + +
      +
      +
      +
      +
      + +
      + Un mot à ajouter ? +
      +
      +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected-images.json new file mode 100644 index 000000000..c72eb5af8 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected-images.json @@ -0,0 +1,47 @@ +[ + "https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/3\/3e\/Flag_of_New_Zealand.svg\/1200px-Flag_of_New_Zealand.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/3\/3e\/Flag_of_New_Zealand.svg\/125px-Flag_of_New_Zealand.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/d\/d3\/Coat_of_arms_of_New_Zealand.svg\/85px-Coat_of_arms_of_New_Zealand.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/2\/29\/NZL_orthographic_NaturalEarth.svg\/250px-NZL_orthographic_NaturalEarth.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/b\/b0\/Increase2.svg\/11px-Increase2.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/a\/ab\/Detail_of_1657_map_Polus_Antarcticus_by_Jan_Janssonius%2C_showing_Nova_Zeelandia.png\/220px-Detail_of_1657_map_Polus_Antarcticus_by_Jan_Janssonius%2C_showing_Nova_Zeelandia.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/4\/4b\/Polynesian_Migration.svg\/290px-Polynesian_Migration.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/2\/22\/Cook_chart_of_New_Zealand.jpg\/170px-Cook_chart_of_New_Zealand.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/8\/87\/Treatyofwaitangi.jpg\/170px-Treatyofwaitangi.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/3\/3b\/1863_Meeting_of_Settlers_and_Maoris_at_Hawke%27s_Bay%2C_New_Zealand.jpg\/290px-1863_Meeting_of_Settlers_and_Maoris_at_Hawke%27s_Bay%2C_New_Zealand.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/a\/ad\/Queen_Elizabeth_II_of_New_Zealand_2.jpg\/152px-Queen_Elizabeth_II_of_New_Zealand_2.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/6\/6f\/Ardern_Cropped.png\/152px-Ardern_Cropped.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/3\/32\/Seddon_Statue_in_Parliament_Grounds.jpg\/220px-Seddon_Statue_in_Parliament_Grounds.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/7\/77\/E_003261_E_Maoris_in_North_Africa_July_1941.jpg\/220px-E_003261_E_Maoris_in_North_Africa_July_1941.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/d\/d4\/ANZAC_Day_service_at_the_National_War_Memorial_-_Flickr_-_NZ_Defence_Force_%2820%29.jpg\/220px-ANZAC_Day_service_at_the_National_War_Memorial_-_Flickr_-_NZ_Defence_Force_%2820%29.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/4\/4b\/NZL_orthographic_NaturalEarth_labelled_en.svg\/400px-NZL_orthographic_NaturalEarth_labelled_en.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/3\/3e\/Flag_of_New_Zealand.svg\/23px-Flag_of_New_Zealand.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/3\/35\/Flag_of_the_Cook_Islands.svg\/23px-Flag_of_the_Cook_Islands.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/0\/01\/Flag_of_Niue.svg\/23px-Flag_of_Niue.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/8\/8e\/Flag_of_Tokelau.svg\/23px-Flag_of_Tokelau.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/a\/a5\/New_Zealand_23_October_2002.jpg\/170px-New_Zealand_23_October_2002.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/4\/44\/Mt_Cook%2C_NZ.jpg\/220px-Mt_Cook%2C_NZ.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/7\/7b\/New_Zealand_moutain_ranges.jpg\/220px-New_Zealand_moutain_ranges.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/e\/e5\/Lake_Gunn.jpg\/269px-Lake_Gunn.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/d\/d4\/Pencarrow_Head%2C_Wellington%2C_New_Zealand_from_Santa_Regina%2C_24_Feb._2007.jpg\/269px-Pencarrow_Head%2C_Wellington%2C_New_Zealand_from_Santa_Regina%2C_24_Feb._2007.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/8\/82\/TeTuatahianui.jpg\/170px-TeTuatahianui.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/2\/2d\/Giant_Haasts_eagle_attacking_New_Zealand_moa.jpg\/220px-Giant_Haasts_eagle_attacking_New_Zealand_moa.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/e\/e1\/Auckland_Waterfrt.jpg\/220px-Auckland_Waterfrt.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/4\/42\/MilfordSound.jpg\/220px-MilfordSound.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/6\/6e\/Fauna_de_Nueva_Zelanda07.JPG\/220px-Fauna_de_Nueva_Zelanda07.JPG", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/1\/11\/Air_New_Zealand%2C_Boeing_787-9_ZK-NZE_%27All_Blacks%27_NRT_%2827091961041%29.jpg\/220px-Air_New_Zealand%2C_Boeing_787-9_ZK-NZE_%27All_Blacks%27_NRT_%2827091961041%29.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/2\/27\/New_Zealandpop.svg\/280px-New_Zealandpop.svg.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/1\/1e\/Auckland_Cbd_%28217403753%29.jpeg\/120px-Auckland_Cbd_%28217403753%29.jpeg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/7\/7b\/Wellington_at_dawn.jpg\/120px-Wellington_at_dawn.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/0\/0e\/Aerial_image_of_Christchurch_suburbs_-_Flickr_-_NZ_Defence_Force_%282%29.jpg\/120px-Aerial_image_of_Christchurch_suburbs_-_Flickr_-_NZ_Defence_Force_%282%29.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/8\/87\/HamiltonNZfromUni.jpg\/120px-HamiltonNZfromUni.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/b\/bb\/Queen_Street_Midtown_Auckland.jpg\/220px-Queen_Street_Midtown_Auckland.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/1\/16\/TeReoMaori2013.png\/220px-TeReoMaori2013.png", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/7\/70\/Ratana_Church_Raetihi.jpg\/170px-Ratana_Church_Raetihi.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/5\/53\/KupeWheke.jpg\/150px-KupeWheke.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/7\/7b\/Hinepare.jpg\/170px-Hinepare.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/8\/89\/Hobbit_holes_reflected_in_water.jpg\/220px-Hobbit_holes_reflected_in_water.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/d\/d2\/Haka_2006.jpg\/220px-Haka_2006.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/9\/91\/Hangi_ingredients.jpg\/220px-Hangi_ingredients.jpg", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/f\/f3\/Gnome-globe.svg\/16px-Gnome-globe.svg.png" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected-metadata.json new file mode 100644 index 000000000..115048eec --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Contributors to Wikimedia projects", + "Direction": "ltr", + "Excerpt": "Coordinates: 42\u00b0S 174\u00b0E\ufeff \/ \ufeff42\u00b0S 174\u00b0E", + "Image": "https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/3\/3e\/Flag_of_New_Zealand.svg\/1200px-Flag_of_New_Zealand.svg.png", + "Title": "New Zealand", + "SiteName": "Wikimedia Foundation, Inc." +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected.html new file mode 100644 index 000000000..4fed8d184 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/expected.html @@ -0,0 +1,3107 @@ +
      + + + + +

      + Coordinates: 42°S 174°E / 42°S 174°E +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +

      + New Zealand +


      +
      +

      Aotearoa  (Māori) +

      +
      +
      +
      +

      Blue field with the Union Flag in the top right corner, and four red stars with white borders to the right. +

      +
      +

      Flag +

      +
      +
      +

      A quartered shield, flanked by two figures, topped with a crown. +

      + +
      +
      +
      + +
      + A map of the hemisphere centred on New Zealand, using an orthographic projection. +

      + Location of New Zealand, including outlying islands, its territorial claim in the Antarctic, and Tokelau +

      +
      + Capital + + Wellington
      + 41°17′S 174°27′E / 41.283°S 174.450°E +
      + Largest city + + Auckland +
      + Official languages + +
      + +
      +
      + Ethnic groups +

      + (2018) +

      +
      +
      + +
      +
      + Demonym(s) + + New Zealander
      + Kiwi (informal) +
      + Government + + Unitary parliamentary constitutional monarchy +
      +

      + • Monarch +

      +
      + Elizabeth II +
      +

      + • Governor-General +

      +
      + Patsy Reddy +
      +

      + • Prime Minister +

      +
      + Jacinda Ardern +
      + Legislature + + Parliament
      + (House of Representatives) +
      + Stages of independence  +

      + from the United Kingdom +

      +
      + + + 7 May 1856 +
      +

      + • Dominion +

      +
      + 26 September 1907 +
      + + +
      + 25 November 1947 +
      + Area +
      +

      + • Total +

      +
      + 268,021 km2 (103,483 sq mi) (75th) +
      +

      + • Water (%) +

      +
      + 1.6[n 4] +
      + Population +
      +

      + • September 2019 estimate +

      +
      + 4,933,210[5] (120th) +
      +

      + • 2018 census +

      +
      + 4,699,755 +
      +

      + • Density +

      +
      + 18.2/km2 (47.1/sq mi) (203rd) +
      + GDP (PPP) + + 2018 estimate +
      +

      + • Total +

      +
      + $199 billion[6] +
      +

      + • Per capita +

      +
      + $40,266[6] +
      + GDP (nominal) + + 2018 estimate +
      +

      + • Total +

      +
      + $206 billion[6] +
      +

      + • Per capita +

      +
      + $41,616[6] +
      + Gini (2014) + + 33.0[7]
      + medium · 22nd +
      + HDI (2017) + + Increase 0.917[8]
      + very high · 16th +
      + Currency + + New Zealand dollar ($) (NZD) +
      + Time zone + + UTC+12 (NZST[n 5]) +
      +

      + • Summer (DST) +

      +
      + UTC+13 (NZDT[n 6]) +
      + Date format + + dd/mm/yyyy
      + yyyy-mm-dd[10] +
      + Driving side + + left +
      + Calling code + + +64 +
      + ISO 3166 code + + NZ +
      + Internet TLD + + .nz +
      +

      + New Zealand (Māori: Aotearoa [aɔˈtɛaɾɔa]) is a sovereign island country in the southwestern Pacific Ocean. The country geographically comprises two main landmasses—the North Island (Te Ika-a-Māui), and the South Island (Te Waipounamu)—and around 600 smaller islands. It has a total land area of 268,000 square kilometres (103,500 sq mi). New Zealand is situated some 2,000 kilometres (1,200 mi) east of Australia across the Tasman Sea and roughly 1,000 kilometres (600 mi) south of the Pacific island areas of New Caledonia, Fiji, and Tonga. Because of its remoteness, it was one of the last lands to be settled by humans. During its long period of isolation, New Zealand developed a distinct biodiversity of animal, fungal, and plant life. The country's varied topography and its sharp mountain peaks, such as the Southern Alps, owe much to the tectonic uplift of land and volcanic eruptions. New Zealand's capital city is Wellington, while its most populous city is Auckland. +

      +

      + Sometime between 1250 and 1300, Polynesians settled in the islands that later were named New Zealand and developed a distinctive Māori culture. In 1642, Dutch explorer Abel Tasman became the first European to sight New Zealand. In 1840, representatives of the United Kingdom and Māori chiefs signed the Treaty of Waitangi, which declared British sovereignty over the islands. In 1841, New Zealand became a colony within the British Empire and in 1907 it became a dominion; it gained full statutory independence in 1947 and the British monarch remained the head of state. Today, the majority of New Zealand's population of 4.9 million is of European descent; the indigenous Māori are the largest minority, followed by Asians and Pacific Islanders. Reflecting this, New Zealand's culture is mainly derived from Māori and early British settlers, with recent broadening arising from increased immigration. The official languages are English, Māori, and New Zealand Sign Language, with English being very dominant. +

      +

      + A developed country, New Zealand ranks highly in international comparisons of national performance, such as quality of life, health, education, protection of civil liberties, and economic freedom. New Zealand underwent major economic changes during the 1980s, which transformed it from a protectionist to a liberalised free-trade economy. The service sector dominates the national economy, followed by the industrial sector, and agriculture; international tourism is a significant source of revenue. Nationally, legislative authority is vested in an elected, unicameral Parliament, while executive political power is exercised by the Cabinet, led by the prime minister, currently Jacinda Ardern. Queen Elizabeth II is the country's monarch and is represented by a governor-general, currently Dame Patsy Reddy. In addition, New Zealand is organised into 11 regional councils and 67 territorial authorities for local government purposes. The Realm of New Zealand also includes Tokelau (a dependent territory); the Cook Islands and Niue (self-governing states in free association with New Zealand); and the Ross Dependency, which is New Zealand's territorial claim in Antarctica. New Zealand is a member of the United Nations, Commonwealth of Nations, ANZUS, Organisation for Economic Co-operation and Development, ASEAN Plus Six, Asia-Pacific Economic Cooperation, the Pacific Community and the Pacific Islands Forum. +

      + +

      + Etymology +

      + +
      +

      Brown square paper with Dutch writing and a thick red, curved line

      +

      Detail from a 1657 map showing the western coastline of "Nova Zeelandia". (In this map, north is at the bottom.) +

      +
      +

      + Dutch explorer Abel Tasman sighted New Zealand in 1642 and named it Staten Land "in honour of the States General" (Dutch parliament). He wrote, "it is possible that this land joins to the Staten Land but it is uncertain",[11] referring to a landmass of the same name at the southern tip of South America, discovered by Jacob Le Maire in 1616.[12][13] In 1645, Dutch cartographers renamed the land Nova Zeelandia after the Dutch province of Zeeland.[14][15] British explorer James Cook subsequently anglicised the name to New Zealand.[16] +

      +

      + Aotearoa (pronounced ; often translated as "land of the long white cloud")[17] is the current Māori name for New Zealand. It is unknown whether Māori had a name for the whole country before the arrival of Europeans, with Aotearoa originally referring to just the North Island.[18] Māori had several traditional names for the two main islands, including Te Ika-a-Māui (the fish of Māui) for the North Island and Te Waipounamu (the waters of greenstone) or Te Waka o Aoraki (the canoe of Aoraki) for the South Island.[19] Early European maps labelled the islands North (North Island), Middle (South Island) and South (Stewart Island / Rakiura).[20] In 1830, mapmakers began to use "North" and "South" on their maps to distinguish the two largest islands and by 1907 this was the accepted norm.[16] The New Zealand Geographic Board discovered in 2009 that the names of the North Island and South Island had never been formalised, and names and alternative names were formalised in 2013. This set the names as North Island or Te Ika-a-Māui, and South Island or Te Waipounamu.[21] For each island, either its English or Māori name can be used, or both can be used together.[21] +

      + +

      + History +

      + +
      +

      One set of arrows point from Taiwan to Melanesia to Fiji/Samoa and then to the Marquesas Islands. The population then spread, some going south to New Zealand and others going north to Hawai'i. A second set start in southern Asia and end in Melanesia.

      +

      The Māori people are most likely descended from people who emigrated from Taiwan to Melanesia and then travelled east through to the Society Islands. After a pause of 70 to 265 years, a new wave of exploration led to the discovery and settlement of New Zealand.[22] +

      +
      +

      + New Zealand was one of the last major landmasses settled by humans. Radiocarbon dating, evidence of deforestation[23] and mitochondrial DNA variability within Māori populations[24] suggest New Zealand was first settled by Eastern Polynesians between 1250 and 1300,[19][25] concluding a long series of voyages through the southern Pacific islands.[26] Over the centuries that followed, these settlers developed a distinct culture now known as Māori. The population was divided into iwi (tribes) and hapū (subtribes) who would sometimes cooperate, sometimes compete and sometimes fight against each other.[27] At some point a group of Māori migrated to Rēkohu, now known as the Chatham Islands, where they developed their distinct Moriori culture.[28][29] The Moriori population was all but wiped out between 1835 and 1862, largely because of Taranaki Māori invasion and enslavement in the 1830s, although European diseases also contributed. In 1862 only 101 survived, and the last known full-blooded Moriori died in 1933.[30] +

      +
      +

      An engraving of a sketched coastline on white background

      +

      Map of the New Zealand coastline as Cook charted it on his first visit in 1769–70. The track of the Endeavour is also shown. +

      +
      +

      + The first Europeans known to have reached New Zealand were Dutch explorer Abel Tasman and his crew in 1642.[31] In a hostile encounter, four crew members were killed and at least one Māori was hit by canister shot.[32] Europeans did not revisit New Zealand until 1769 when British explorer James Cook mapped almost the entire coastline.[31] Following Cook, New Zealand was visited by numerous European and North American whaling, sealing and trading ships. They traded European food, metal tools, weapons and other goods for timber, Māori food, artefacts and water.[33] The introduction of the potato and the musket transformed Māori agriculture and warfare. Potatoes provided a reliable food surplus, which enabled longer and more sustained military campaigns.[34] The resulting intertribal Musket Wars encompassed over 600 battles between 1801 and 1840, killing 30,000–40,000 Māori.[35] From the early 19th century, Christian missionaries began to settle New Zealand, eventually converting most of the Māori population.[36] The Māori population declined to around 40% of its pre-contact level during the 19th century; introduced diseases were the major factor.[37] +

      +
      +

      A torn sheet of paper

      +
      +

      + In 1788 Captain Arthur Phillip assumed the position of Governor of the new British colony of New South Wales which according to his commission included New Zealand.[38] The British Government appointed James Busby as British Resident to New Zealand in 1832 following a petition from northern Māori.[39] In 1835, following an announcement of impending French settlement by Charles de Thierry, the nebulous United Tribes of New Zealand sent a Declaration of Independence to King William IV of the United Kingdom asking for protection.[39] Ongoing unrest, the proposed settlement of New Zealand by the New Zealand Company (which had already sent its first ship of surveyors to buy land from Māori) and the dubious legal standing of the Declaration of Independence prompted the Colonial Office to send Captain William Hobson to claim sovereignty for the United Kingdom and negotiate a treaty with the Māori.[40] The Treaty of Waitangi was first signed in the Bay of Islands on 6 February 1840.[41] In response to the New Zealand Company's attempts to establish an independent settlement in Wellington[42] and French settlers purchasing land in Akaroa,[43] Hobson declared British sovereignty over all of New Zealand on 21 May 1840, even though copies of the Treaty were still circulating throughout the country for Māori to sign.[44] With the signing of the Treaty and declaration of sovereignty the number of immigrants, particularly from the United Kingdom, began to increase.[45] +

      +
      +

      Black and white engraving depicting a crowd of people

      +
      +

      + New Zealand, still part of the colony of New South Wales, became a separate Colony of New Zealand on 1 July 1841.[46] Armed conflict began between the Colonial government and Māori in 1843 with the Wairau Affray over land and disagreements over sovereignty. These conflicts, mainly in the North Island, saw thousands of Imperial troops and the Royal Navy come to New Zealand and became known as the New Zealand Wars. Following these armed conflicts, large amounts of Māori land was confiscated by the government to meet settler demands.[47] +

      +

      + The colony gained a representative government in 1852 and the first Parliament met in 1854.[48] In 1856 the colony effectively became self-governing, gaining responsibility over all domestic matters other than native policy.[48] (Control over native policy was granted in the mid-1860s.[48]) Following concerns that the South Island might form a separate colony, premier Alfred Domett moved a resolution to transfer the capital from Auckland to a locality near Cook Strait.[49] Wellington was chosen for its central location, with Parliament officially sitting there for the first time in 1865.[50] +

      +

      + In 1891 the Liberal Party came to power as the first organised political party.[51] The Liberal Government, led by Richard Seddon for most of its period in office,[52] passed many important social and economic measures. In 1893 New Zealand was the first nation in the world to grant all women the right to vote[51] and in 1894 pioneered the adoption of compulsory arbitration between employers and unions.[53] +

      +

      + In 1907, at the request of the New Zealand Parliament, King Edward VII proclaimed New Zealand a Dominion within the British Empire,[54] reflecting its self-governing status.[55] In 1947 the country adopted the Statute of Westminster, confirming that the British Parliament could no longer legislate for New Zealand without the consent of New Zealand.[48] +

      +

      + Early in the 20th century, New Zealand was involved in world affairs, fighting in the First and Second World Wars[56] and suffering through the Great Depression.[57] The depression led to the election of the First Labour Government and the establishment of a comprehensive welfare state and a protectionist economy.[58] New Zealand experienced increasing prosperity following the Second World War[59] and Māori began to leave their traditional rural life and move to the cities in search of work.[60] A Māori protest movement developed, which criticised Eurocentrism and worked for greater recognition of Māori culture and of the Treaty of Waitangi.[61] In 1975, a Waitangi Tribunal was set up to investigate alleged breaches of the Treaty, and it was enabled to investigate historic grievances in 1985.[41] The government has negotiated settlements of these grievances with many iwi,[62] although Māori claims to the foreshore and seabed have proved controversial in the 2000s.[63][64] +

      +

      + Government and politics +

      + +
      +
      +

      The Queen wearing her New Zealand insignia +

      + +
      +
      +

      A smiling woman wearing a black dress +

      + +
      +
      +

      + New Zealand is a constitutional monarchy with a parliamentary democracy,[65] although its constitution is not codified.[66] Elizabeth II is the Queen of New Zealand[67] and thus the head of state.[68] The Queen is represented by the governor-general, whom she appoints on the advice of the prime minister.[69] The governor-general can exercise the Crown's prerogative powers, such as reviewing cases of injustice and making appointments of ministers, ambassadors and other key public officials,[70] and in rare situations, the reserve powers (e.g. the power to dissolve parliament or refuse the royal assent of a bill into law).[71] The powers of the monarch and the governor-general are limited by constitutional constraints and they cannot normally be exercised without the advice of ministers.[71] +

      +

      + The New Zealand Parliament holds legislative power and consists of the Queen and the House of Representatives.[72] It also included an upper house, the Legislative Council, until this was abolished in 1950.[72] The supremacy of parliament over the Crown and other government institutions was established in England by the Bill of Rights 1689 and has been ratified as law in New Zealand.[72] The House of Representatives is democratically elected and a government is formed from the party or coalition with the majority of seats. If no majority is formed, a minority government can be formed if support from other parties during confidence and supply votes is assured.[72] The governor-general appoints ministers under advice from the prime minister, who is by convention the parliamentary leader of the governing party or coalition.[73] Cabinet, formed by ministers and led by the prime minister, is the highest policy-making body in government and responsible for deciding significant government actions.[74] Members of Cabinet make major decisions collectively, and are therefore collectively responsible for the consequences of these decisions.[75] +

      +

      + A parliamentary general election must be called no later than three years after the previous election.[76] Almost all general elections between 1853 and 1993 were held under the first-past-the-post voting system.[77] Since the 1996 election, a form of proportional representation called mixed-member proportional (MMP) has been used.[66] Under the MMP system, each person has two votes; one is for a candidate standing in the voter's electorate and the other is for a party. Since the 2014 election, there have been 71 electorates (which include seven Māori electorates in which only Māori can optionally vote),[78] and the remaining 49 of the 120 seats are assigned so that representation in parliament reflects the party vote, with the threshold that a party must win at least one electorate or 5% of the total party vote before it is eligible for a seat.[79] +

      +
      +

      A block of buildings fronted by a large statue.

      +
      +

      + Elections since the 1930s have been dominated by two political parties, National and Labour.[77] Between March 2005 and August 2006, New Zealand became the first country in the world in which all the highest offices in the land—head of state, governor-general, prime minister, speaker and chief justice—were occupied simultaneously by women.[80] The current prime minister is Jacinda Ardern, who has been in office since 26 October 2017.[81] She is the country's third female prime minister.[82] +

      +

      + New Zealand's judiciary, headed by the chief justice,[83] includes the Supreme Court, Court of Appeal, the High Court, and subordinate courts.[84] Judges and judicial officers are appointed non-politically and under strict rules regarding tenure to help maintain judicial independence.[66] This theoretically allows the judiciary to interpret the law based solely on the legislation enacted by Parliament without other influences on their decisions.[85] +

      +

      + New Zealand is identified as one of the world's most stable and well-governed states.[86] As at 2017, the country was ranked fourth in the strength of its democratic institutions,[87] and first in government transparency and lack of corruption.[88] A 2017 Human Rights Report by the U.S. Department of State noted that the government generally respected the rights of individuals, but voiced concerns regarding the social status of the Māori population.[89] New Zealand ranks highly for civic participation in the political process, with 77% voter turnout during recent elections, compared to an OECD average of 69%.[90] +

      + +

      + Foreign relations and military +

      + +
      +

      A squad of men kneel in the desert sand while performing a war dance

      +
      +

      + Early colonial New Zealand allowed the British Government to determine external trade and be responsible for foreign policy.[91] The 1923 and 1926 Imperial Conferences decided that New Zealand should be allowed to negotiate its own political treaties and the first commercial treaty was ratified in 1928 with Japan. On 3 September 1939 New Zealand allied itself with Britain and declared war on Germany with Prime Minister Michael Joseph Savage proclaiming, "Where she goes, we go; where she stands, we stand."[92] +

      +

      + In 1951 the United Kingdom became increasingly focused on its European interests,[93] while New Zealand joined Australia and the United States in the ANZUS security treaty.[94] The influence of the United States on New Zealand weakened following protests over the Vietnam War,[95] the refusal of the United States to admonish France after the sinking of the Rainbow Warrior,[96] disagreements over environmental and agricultural trade issues and New Zealand's nuclear-free policy.[97][98] Despite the United States' suspension of ANZUS obligations the treaty remained in effect between New Zealand and Australia, whose foreign policy has followed a similar historical trend.[99] Close political contact is maintained between the two countries, with free trade agreements and travel arrangements that allow citizens to visit, live and work in both countries without restrictions.[100] In 2013 there were about 650,000 New Zealand citizens living in Australia, which is equivalent to 15% of the resident population of New Zealand.[101] +

      +
      +

      A soldier in a green army uniform faces forwards

      +

      Anzac Day service at the National War Memorial +

      +
      +

      + New Zealand has a strong presence among the Pacific Island countries. A large proportion of New Zealand's aid goes to these countries and many Pacific people migrate to New Zealand for employment.[102] Permanent migration is regulated under the 1970 Samoan Quota Scheme and the 2002 Pacific Access Category, which allow up to 1,100 Samoan nationals and up to 750 other Pacific Islanders respectively to become permanent New Zealand residents each year. A seasonal workers scheme for temporary migration was introduced in 2007 and in 2009 about 8,000 Pacific Islanders were employed under it.[103] A regional power,[104] New Zealand is involved in the Pacific Islands Forum, the Pacific Community, Asia-Pacific Economic Cooperation and the Association of Southeast Asian Nations Regional Forum (including the East Asia Summit).[100] New Zealand is a member of the United Nations,[105] the Commonwealth of Nations[106] and the Organisation for Economic Co-operation and Development (OECD),[107] and participates in the Five Power Defence Arrangements.[108] +

      +

      + New Zealand's military services—the Defence Force—comprise the New Zealand Army, the Royal New Zealand Air Force and the Royal New Zealand Navy.[109] New Zealand's national defence needs are modest, since a direct attack is unlikely.[110] However, its military has had a global presence. The country fought in both world wars, with notable campaigns in Gallipoli, Crete,[111] El Alamein[112] and Cassino.[113] The Gallipoli campaign played an important part in fostering New Zealand's national identity[114][115] and strengthened the ANZAC tradition it shares with Australia.[116] +

      +

      + In addition to Vietnam and the two world wars, New Zealand fought in the Second Boer War,[117] the Korean War,[118] the Malayan Emergency,[119] the Gulf War and the Afghanistan War. It has contributed forces to several regional and global peacekeeping missions, such as those in Cyprus, Somalia, Bosnia and Herzegovina, the Sinai, Angola, Cambodia, the Iran–Iraq border, Bougainville, East Timor, and the Solomon Islands.[120] +

      +

      + Local government and external territories +

      + +
      +

      Map with the North, South, Stewart/Rakiura, Tokelau, Cook, Niue, Kermadec, Chatham, Bounty, Antipodes, Snare, Auckland and Campbell Islands highlighted. New Zealand's segment of Antarctica (the Ross Dependency) is also highlighted.

      +
      +

      + The early European settlers divided New Zealand into provinces, which had a degree of autonomy.[121] Because of financial pressures and the desire to consolidate railways, education, land sales and other policies, government was centralised and the provinces were abolished in 1876.[122] The provinces are remembered in regional public holidays[123] and sporting rivalries.[124] +

      +

      + Since 1876, various councils have administered local areas under legislation determined by the central government.[121][125] In 1989, the government reorganised local government into the current two-tier structure of regional councils and territorial authorities.[126] The 249 municipalities[126] that existed in 1975 have now been consolidated into 67 territorial authorities and 11 regional councils.[127] The regional councils' role is to regulate "the natural environment with particular emphasis on resource management",[126] while territorial authorities are responsible for sewage, water, local roads, building consents and other local matters.[128][129] Five of the territorial councils are unitary authorities and also act as regional councils.[129] The territorial authorities consist of 13 city councils, 53 district councils, and the Chatham Islands Council. While officially the Chatham Islands Council is not a unitary authority, it undertakes many functions of a regional council.[130] +

      +

      + The Realm of New Zealand, one of 16 Commonwealth realms,[131] is the entire area over which the Queen of New Zealand is sovereign, and comprises New Zealand, Tokelau, the Ross Dependency, the Cook Islands and Niue.[65] The Cook Islands and Niue are self-governing states in free association with New Zealand.[132][133] The New Zealand Parliament cannot pass legislation for these countries, but with their consent can act on behalf of them in foreign affairs and defence. Tokelau is classified as a non-self-governing territory, but is administered by a council of three elders (one from each Tokelauan atoll).[134] The Ross Dependency is New Zealand's territorial claim in Antarctica, where it operates the Scott Base research facility.[135] New Zealand nationality law treats all parts of the realm equally, so most people born in New Zealand, the Cook Islands, Niue, Tokelau and the Ross Dependency are New Zealand citizens.[136][n 7] +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
        +
      • + v +
      • +
      • + t +
      • +
      • + e +
      • +
      +
      +

      + Administrative divisions of the Realm of New Zealand +

      +
      + Countries + +  New Zealand + +   + +   + +  Cook Islands + +  Niue +
      + Regions + + 11 non-unitary regions + + 5 unitary regions + + Chatham Islands + +   + + Outlying islands outside any regional authority
      + (the Kermadec Islands, Three Kings Islands, and Subantarctic Islands) +
      + Ross Dependency + +  Tokelau + + 15 islands + + 14 villages +
      + Territorial authorities + + 13 cities and 53 districts +
      + Notes + + Some districts lie in more than one region + + These combine the regional and the territorial authority levels in one + + Special territorial authority + + The outlying Solander Islands form part of the Southland Region + + New Zealand's Antarctic territory + + Non-self-governing territory of New Zealand + + States in free association with New Zealand +
      +

      + Environment +

      + +

      + Geography +

      + + +
      +

      Islands of New Zealand as seen from satellite

      +
      +

      + New Zealand is located near the centre of the water hemisphere and is made up of two main islands and a number of smaller islands. The two main islands (the North Island, or Te Ika-a-Māui, and the South Island, or Te Waipounamu) are separated by Cook Strait, 22 kilometres (14 mi) wide at its narrowest point.[138] Besides the North and South Islands, the five largest inhabited islands are Stewart Island (across the Foveaux Strait), Chatham Island, Great Barrier Island (in the Hauraki Gulf),[139] D'Urville Island (in the Marlborough Sounds)[140] and Waiheke Island (about 22 km (14 mi) from central Auckland).[141] +

      + +
      +
      +

      A large mountain with a lake in the foreground +

      + +
      +
      +

      Snow-capped mountain range +

      +

      + The Southern Alps stretch for 500 kilometres down the South Island +

      +
      +
      +

      + New Zealand is long and narrow (over 1,600 kilometres (990 mi) along its north-north-east axis with a maximum width of 400 kilometres (250 mi)),[142] with about 15,000 km (9,300 mi) of coastline[143] and a total land area of 268,000 square kilometres (103,500 sq mi).[144] Because of its far-flung outlying islands and long coastline, the country has extensive marine resources. Its exclusive economic zone is one of the largest in the world, covering more than 15 times its land area.[145] +

      +

      + The South Island is the largest landmass of New Zealand. It is divided along its length by the Southern Alps.[146] There are 18 peaks over 3,000 metres (9,800 ft), the highest of which is Aoraki / Mount Cook at 3,754 metres (12,316 ft).[147] Fiordland's steep mountains and deep fiords record the extensive ice age glaciation of this southwestern corner of the South Island.[148] The North Island is less mountainous but is marked by volcanism.[149] The highly active Taupo Volcanic Zone has formed a large volcanic plateau, punctuated by the North Island's highest mountain, Mount Ruapehu (2,797 metres (9,177 ft)). The plateau also hosts the country's largest lake, Lake Taupo,[150] nestled in the caldera of one of the world's most active supervolcanoes.[151] +

      +

      + The country owes its varied topography, and perhaps even its emergence above the waves, to the dynamic boundary it straddles between the Pacific and Indo-Australian Plates.[152] New Zealand is part of Zealandia, a microcontinent nearly half the size of Australia that gradually submerged after breaking away from the Gondwanan supercontinent.[153] About 25 million years ago, a shift in plate tectonic movements began to contort and crumple the region. This is now most evident in the Southern Alps, formed by compression of the crust beside the Alpine Fault. Elsewhere the plate boundary involves the subduction of one plate under the other, producing the Puysegur Trench to the south, the Hikurangi Trench east of the North Island, and the Kermadec and Tonga Trenches[154] further north.[152] +

      +

      + New Zealand is part of a region known as Australasia, together with Australia.[155] It also forms the southwestern extremity of the geographic and ethnographic region called Polynesia.[156] The term Oceania is often used to denote the wider region encompassing the Australian continent, New Zealand and various islands in the Pacific Ocean that are not included in the seven-continent model.[157] +

      + + +

      + Climate +

      + +

      + New Zealand's climate is predominantly temperate maritime (Köppen: Cfb), with mean annual temperatures ranging from 10 °C (50 °F) in the south to 16 °C (61 °F) in the north.[158] Historical maxima and minima are 42.4 °C (108.32 °F) in Rangiora, Canterbury and −25.6 °C (−14.08 °F) in Ranfurly, Otago.[159] Conditions vary sharply across regions from extremely wet on the West Coast of the South Island to almost semi-arid in Central Otago and the Mackenzie Basin of inland Canterbury and subtropical in Northland.[160] Of the seven largest cities, Christchurch is the driest, receiving on average only 640 millimetres (25 in) of rain per year and Wellington the wettest, receiving almost twice that amount.[161] Auckland, Wellington and Christchurch all receive a yearly average of more than 2,000 hours of sunshine. The southern and southwestern parts of the South Island have a cooler and cloudier climate, with around 1,400–1,600 hours; the northern and northeastern parts of the South Island are the sunniest areas of the country and receive about 2,400–2,500 hours.[162] The general snow season is early June until early October, though cold snaps can occur outside this season.[163] Snowfall is common in the eastern and southern parts of the South Island and mountain areas across the country.[158] +

      +

      + The table below lists climate normals for the warmest and coldest months in New Zealand's six largest cities. North Island cities are generally warmest in February. South Island cities are warmest in January. +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + Average daily maximum and minimum temperatures for the six largest cities of New Zealand[164] +
      + Location + + Jan/Feb (°C) + + Jan/Feb (°F) + + July (°C) + + July (°F) +
      + Auckland + + 23/16 + + 74/60 + + 14/7 + + 58/45 +
      + Wellington + + 20/13 + + 68/56 + + 11/6 + + 52/42 +
      + Christchurch + + 22/12 + + 72/53 + + 10/0 + + 51/33 +
      + Hamilton + + 24/13 + + 75/56 + + 14/4 + + 57/39 +
      + Tauranga + + 24/15 + + 75/59 + + 14/6 + + 58/42 +
      + Dunedin + + 19/11 + + 66/53 + + 10/3 + + 50/37 +
      +

      + Biodiversity +

      + +
      +

      Kiwi amongst sticks

      +

      The endemic flightless kiwi is a national icon. +

      +
      +

      + New Zealand's geographic isolation for 80 million years[165] and island biogeography has influenced evolution of the country's species of animals, fungi and plants. Physical isolation has caused biological isolation, resulting in a dynamic evolutionary ecology with examples of very distinctive plants and animals as well as populations of widespread species.[166][167] About 82% of New Zealand's indigenous vascular plants are endemic, covering 1,944 species across 65 genera.[168][169] The number of fungi recorded from New Zealand, including lichen-forming species, is not known, nor is the proportion of those fungi which are endemic, but one estimate suggests there are about 2,300 species of lichen-forming fungi in New Zealand[168] and 40% of these are endemic.[170] The two main types of forest are those dominated by broadleaf trees with emergent podocarps, or by southern beech in cooler climates.[171] The remaining vegetation types consist of grasslands, the majority of which are tussock.[172] +

      +

      + Before the arrival of humans, an estimated 80% of the land was covered in forest, with only high alpine, wet, infertile and volcanic areas without trees.[173] Massive deforestation occurred after humans arrived, with around half the forest cover lost to fire after Polynesian settlement.[174] Much of the remaining forest fell after European settlement, being logged or cleared to make room for pastoral farming, leaving forest occupying only 23% of the land.[175] +

      +
      +

      An artist's rendition of a Haast's eagle attacking two moa

      +

      The giant Haast's eagle died out when humans hunted its main prey, the moa, to extinction. +

      +
      +

      + The forests were dominated by birds, and the lack of mammalian predators led to some like the kiwi, kakapo, weka and takahē evolving flightlessness.[176] The arrival of humans, associated changes to habitat, and the introduction of rats, ferrets and other mammals led to the extinction of many bird species, including large birds like the moa and Haast's eagle.[177][178] +

      +

      + Other indigenous animals are represented by reptiles (tuatara, skinks and geckos), frogs,[179] spiders,[180] insects (weta)[181] and snails.[182] Some, such as the tuatara, are so unique that they have been called living fossils.[183] Three species of bats (one since extinct) were the only sign of native land mammals in New Zealand until the 2006 discovery of bones from a unique, mouse-sized land mammal at least 16 million years old.[184][185] Marine mammals however are abundant, with almost half the world's cetaceans (whales, dolphins, and porpoises) and large numbers of fur seals reported in New Zealand waters.[186] Many seabirds breed in New Zealand, a third of them unique to the country.[187] More penguin species are found in New Zealand than in any other country.[188] +

      +

      + Since human arrival, almost half of the country's vertebrate species have become extinct, including at least fifty-one birds, three frogs, three lizards, one freshwater fish, and one bat. Others are endangered or have had their range severely reduced.[177] However, New Zealand conservationists have pioneered several methods to help threatened wildlife recover, including island sanctuaries, pest control, wildlife translocation, fostering, and ecological restoration of islands and other selected areas.[189][190][191][192] +

      + +

      + Economy +

      + + +
      +

      Boats docked in blue-green water. Plate glass skyscrapers rising up in the background.

      +
      +

      + New Zealand has an advanced market economy,[193] ranked 16th in the 2018 Human Development Index[8] and third in the 2018 Index of Economic Freedom.[194] It is a high-income economy with a nominal gross domestic product (GDP) per capita of US$36,254.[6] The currency is the New Zealand dollar, informally known as the "Kiwi dollar"; it also circulates in the Cook Islands (see Cook Islands dollar), Niue, Tokelau, and the Pitcairn Islands.[195] +

      +

      + Historically, extractive industries have contributed strongly to New Zealand's economy, focussing at different times on sealing, whaling, flax, gold, kauri gum, and native timber.[196] The first shipment of refrigerated meat on the Dunedin in 1882 led to the establishment of meat and dairy exports to Britain, a trade which provided the basis for strong economic growth in New Zealand.[197] High demand for agricultural products from the United Kingdom and the United States helped New Zealanders achieve higher living standards than both Australia and Western Europe in the 1950s and 1960s.[198] In 1973, New Zealand's export market was reduced when the United Kingdom joined the European Economic Community[199] and other compounding factors, such as the 1973 oil and 1979 energy crises, led to a severe economic depression.[200] Living standards in New Zealand fell behind those of Australia and Western Europe, and by 1982 New Zealand had the lowest per-capita income of all the developed nations surveyed by the World Bank.[201] In the mid-1980s New Zealand deregulated its agricultural sector by phasing out subsidies over a three-year period.[202][203] Since 1984, successive governments engaged in major macroeconomic restructuring (known first as Rogernomics and then Ruthanasia), rapidly transforming New Zealand from a protected and highly regulated economy to a liberalised free-trade economy.[204][205] +

      +
      +

      Blue water against a backdrop of snow-capped mountains

      +

      Milford Sound is one of New Zealand's most famous tourist destinations.[206] +

      +
      +

      + Unemployment peaked above 10% in 1991 and 1992,[207] following the 1987 share market crash, but eventually fell to a record low (since 1986) of 3.7% in 2007 (ranking third from twenty-seven comparable OECD nations).[207] However, the global financial crisis that followed had a major impact on New Zealand, with the GDP shrinking for five consecutive quarters, the longest recession in over thirty years,[208][209] and unemployment rising back to 7% in late 2009.[210] Unemployment rates for different age groups follow similar trends, but are consistently higher among youth. In the December 2014 quarter, the general unemployment rate was around 5.8%, while the unemployment rate for youth aged 15 to 21 was 15.6%.[207] New Zealand has experienced a series of "brain drains" since the 1970s[211] that still continue today.[212] Nearly one quarter of highly skilled workers live overseas, mostly in Australia and Britain, which is the largest proportion from any developed nation.[213] In recent decades, however, a "brain gain" has brought in educated professionals from Europe and less developed countries.[214][215] Today New Zealand's economy benefits from a high level of innovation.[216] +

      +

      + Trade +

      +

      + New Zealand is heavily dependent on international trade,[217] particularly in agricultural products.[218] Exports account for 24% of its output,[143] making New Zealand vulnerable to international commodity prices and global economic slowdowns. Food products made up 55% of the value of all the country's exports in 2014; wood was the second largest earner (7%).[219] New Zealand's main trading partners, as at June 2018, are China (NZ$27.8b), Australia ($26.2b), the European Union ($22.9b), the United States ($17.6b), and Japan ($8.4b).[220] On 7 April 2008, New Zealand and China signed the New Zealand–China Free Trade Agreement, the first such agreement China has signed with a developed country.[221] The service sector is the largest sector in the economy, followed by manufacturing and construction and then farming and raw material extraction.[143] Tourism plays a significant role in the economy, contributing $12.9 billion (or 5.6%) to New Zealand's total GDP and supporting 7.5% of the total workforce in 2016.[222] International visitor arrivals are expected to increase at a rate of 5.4% annually up to 2022.[222] +

      +
      +

      A Romney ewe with her two lambs

      +

      Wool has historically been one of New Zealand's major exports. +

      +
      +

      + Wool was New Zealand's major agricultural export during the late 19th century.[196] Even as late as the 1960s it made up over a third of all export revenues,[196] but since then its price has steadily dropped relative to other commodities[223] and wool is no longer profitable for many farmers.[224] In contrast dairy farming increased, with the number of dairy cows doubling between 1990 and 2007,[225] to become New Zealand's largest export earner.[226] In the year to June 2018, dairy products accounted for 17.7% ($14.1 billion) of total exports,[220] and the country's largest company, Fonterra, controls almost one-third of the international dairy trade.[227] Other exports in 2017-18 were meat (8.8%), wood and wood products (6.2%), fruit (3.6%), machinery (2.2%) and wine (2.1%).[220] New Zealand's wine industry has followed a similar trend to dairy, the number of vineyards doubling over the same period,[228] overtaking wool exports for the first time in 2007.[229][230] +

      +

      + Infrastructure +

      +
      +

      A mid-size jet airliner in flight. The plane livery is all-black and features a New Zealand silver fern mark.

      +
      +

      + In 2015, renewable energy, primarily geothermal and hydroelectric power, generated 40.1% of New Zealand's gross energy supply.[231] Geothermal power alone accounted for 22% of New Zealand's energy in 2015.[231] +

      +

      + The provision of water supply and sanitation is generally of good quality. Regional authorities provide water abstraction, treatment and distribution infrastructure to most developed areas.[232][233] +

      +

      + New Zealand's transport network comprises 94,000 kilometres (58,410 mi) of roads, including 199 kilometres (124 mi) of motorways,[234] and 4,128 kilometres (2,565 mi) of railway lines.[143] Most major cities and towns are linked by bus services, although the private car is the predominant mode of transport.[235] The railways were privatised in 1993, but were re-nationalised by the government in stages between 2004 and 2008. The state-owned enterprise KiwiRail now operates the railways, with the exception of commuter services in Auckland and Wellington which are operated by Transdev[236] and Metlink,[237] respectively. Railways run the length of the country, although most lines now carry freight rather than passengers.[238] Most international visitors arrive via air[239] and New Zealand has six international airports, but currently only the Auckland and Christchurch airports connect directly with countries other than Australia or Fiji.[240] +

      +

      + The New Zealand Post Office had a monopoly over telecommunications in New Zealand until 1987 when Telecom New Zealand was formed, initially as a state-owned enterprise and then privatised in 1990.[241] Chorus, which was split from Telecom (now Spark) in 2011,[242] still owns the majority of the telecommunications infrastructure, but competition from other providers has increased.[241] A large-scale rollout of gigabit-capable fibre to the premises, branded as Ultra-Fast Broadband, began in 2009 with a target of being available to 87% of the population by 2022.[243] As of 2017, the United Nations International Telecommunication Union ranks New Zealand 13th in the development of information and communications infrastructure.[244] +

      +

      + Demography +

      + +
      +

      Stationary population pyramid broken down into 21 age ranges.

      +
      +

      + The 2013 New Zealand census enumerated a resident population of 4,242,048, an increase of 5.3% over the 2006 figure.[245][n 8] As of September 2019, the total population has risen to an estimated 4,933,210.[5] +

      +

      + New Zealand is a predominantly urban country, with 73.0% of the population living in the seventeen main urban areas (i.e. population 30,000 or greater) and 55.1% living in the four largest cities of Auckland, Christchurch, Wellington, and Hamilton.[247] New Zealand cities generally rank highly on international livability measures. For instance, in 2016 Auckland was ranked the world's third most liveable city and Wellington the twelfth by the Mercer Quality of Living Survey.[248] +

      +

      + Life expectancy for New Zealanders in 2012 was 84 years for females, and 80.2 years for males.[249] Life expectancy at birth is forecast to increase from 80 years to 85 years in 2050 and infant mortality is expected to decline.[250] New Zealand's fertility rate of 2.1 is relatively high for a developed country, and natural births account for a significant proportion of population growth. Consequently, the country has a young population compared to most industrialised nations, with 20% of New Zealanders being 14 years old or younger.[143] In 2018 the median age of the New Zealand population was 38.1 years.[251] By 2050 the median age is projected to rise to 43 years and the percentage of people 60 years of age and older to rise from 18% to 29%.[250] In 2008 the leading cause of premature death was cancer, at 29.8%, followed by ischaemic heart disease, 19.7%, and then cerebrovascular disease, 9.2%.[252] As of 2016, total expenditure on health care (including private sector spending) is 9.2% of GDP.[253]
      +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      +
        +
      • + v +
      • +
      • + t +
      • +
      • + e +
      • +
      +
      +
      +

      Largest urban areas in New Zealand

      +

      Statistics New Zealand June 2018 estimate (NZSAC92 boundaries)[254] +

      +
      +
      + Rank + + Name + + Region + + Pop. + + Rank + + Name + + Region + + Pop. +
      + Auckland
      + Auckland
      + Wellington
      + Wellington +
      + 1 + + Auckland + + Auckland + + 1,628,900 + + 11 + + Whangarei + + Northland + + 58,800 + + Christchurch
      + Christchurch
      + Hamilton
      + Hamilton +
      + 2 + + Wellington + + Wellington + + 418,500 + + 12 + + New Plymouth + + Taranaki + + 58,300 +
      + 3 + + Christchurch + + Canterbury + + 404,500 + + 13 + + Invercargill + + Southland + + 51,200 +
      + 4 + + Hamilton + + Waikato + + 241,200 + + 14 + + Kapiti + + Wellington + + 42,700 +
      + 5 + + Tauranga + + Bay of Plenty + + 141,600 + + 15 + + Whanganui + + Manawatu-Wanganui + + 40,900 +
      + 6 + + Napier-Hastings + + Hawke's Bay + + 134,500 + + 16 + + Gisborne + + Gisborne + + 37,200 +
      + 7 + + Dunedin + + Otago + + 122,000 + + 17 + + Blenheim + + Marlborough + + 31,600 +
      + 8 + + Palmerston North + + Manawatu-Wanganui + + 86,600 + + 18 + + Pukekohe + + Auckland + + 31,400 +
      + 9 + + Nelson + + Nelson + + 67,500 + + 19 + + Timaru + + Canterbury + + 29,100 +
      + 10 + + Rotorua + + Bay of Plenty + + 59,500 + + 20 + + Taupo + + Waikato + + 24,700 +
      + +

      + Ethnicity and immigration +

      + +
      +

      Pedestrians crossing a wide street which is flanked by storefronts

      +

      Pedestrians on Queen Street in Auckland, an ethnically diverse city +

      +
      +

      + In the 2013 census, 74.0% of New Zealand residents identified ethnically as European, and 14.9% as Māori. Other major ethnic groups include Asian (11.8%) and Pacific peoples (7.4%), two-thirds of whom live in the Auckland Region.[255][n 3] The population has become more diverse in recent decades: in 1961, the census reported that the population of New Zealand was 92% European and 7% Māori, with Asian and Pacific minorities sharing the remaining 1%.[256] +

      +

      + While the demonym for a New Zealand citizen is New Zealander, the informal "Kiwi" is commonly used both internationally[257] and by locals.[258] The Māori loanword Pākehā has been used to refer to New Zealanders of European descent, although others reject this appellation.[259][260] The word Pākehā today is increasingly used to refer to all non-Polynesian New Zealanders.[261] +

      +

      + The Māori were the first people to reach New Zealand, followed by the early European settlers. Following colonisation, immigrants were predominantly from Britain, Ireland and Australia because of restrictive policies similar to the White Australia policy.[262] There was also significant Dutch, Dalmatian,[263] German, and Italian immigration, together with indirect European immigration through Australia, North America, South America and South Africa.[264][265] Net migration increased after the Second World War; in the 1970s and 1980s policies were relaxed and immigration from Asia was promoted.[265][266] In 2009–10, an annual target of 45,000–50,000 permanent residence approvals was set by the New Zealand Immigration Service—more than one new migrant for every 100 New Zealand residents.[267] Just over 25% of New Zealand's population was born overseas, with the majority (52%) living in the Auckland Region. The United Kingdom remains the largest source of New Zealand's overseas population, with a quarter of all overseas-born New Zealanders born there; other major sources of New Zealand's overseas-born population are China, India, Australia, South Africa, Fiji and Samoa.[268] The number of fee-paying international students increased sharply in the late 1990s, with more than 20,000 studying in public tertiary institutions in 2002.[269] +

      +

      + Language +

      + +
      +

      Map of New Zealand showing the percentage of people in each census area unit who speak Māori. Areas of the North Island exhibit the highest Māori proficiency.

      +

      Speakers of Māori according to the 2013 census[270]

        Less than 5% +

      +

        More than 5% +

      +

        More than 10% +

      +

        More than 20% +

      +

        More than 30% +

      +

        More than 40% +

      +

        More than 50% +

      +
      +
      +

      + English is the predominant language in New Zealand, spoken by 96.1% of the population.[271] New Zealand English is similar to Australian English and many speakers from the Northern Hemisphere are unable to tell the accents apart.[272] The most prominent differences between the New Zealand English dialect and other English dialects are the shifts in the short front vowels: the short-"i" sound (as in "kit") has centralised towards the schwa sound (the "a" in "comma" and "about"); the short-"e" sound (as in "dress") has moved towards the short-"i" sound; and the short-"a" sound (as in "trap") has moved to the short-"e" sound.[273] +

      +

      + After the Second World War, Māori were discouraged from speaking their own language (te reo Māori) in schools and workplaces and it existed as a community language only in a few remote areas.[274] It has recently undergone a process of revitalisation,[275] being declared one of New Zealand's official languages in 1987,[276] and is spoken by 3.7% of the population.[271][n 9] There are now Māori language immersion schools and two television channels that broadcast predominantly in Māori.[278] Many places have both their Māori and English names officially recognised.[279] +

      +

      + As recorded in the 2013 census,[271] Samoan is the most widely spoken non-official language (2.2%),[n 10] followed by Hindi (1.7%), "Northern Chinese" (including Mandarin, 1.3%) and French (1.2%). 20,235 people (0.5%) reported the ability to use New Zealand Sign Language. It was declared one of New Zealand's official languages in 2006.[280] +

      +

      + Religion +

      + + +
      +

      Simple white building with two red domed towers

      +

      A Rātana church on a hill near Raetihi. The two-tower construction is characteristic of Rātana buildings. +

      +
      +

      + Christianity is the predominant religion in New Zealand, although its society is among the most secular in the world.[281][282] In the 2018 census, 51.4% of the population identified with one or more religions, including 38.6% identifying as Christians. Another 48.6% indicated that they had no religion.[n 11] The main Christian denominations are, by number of adherents, Roman Catholicism (10.1%), Anglicanism (6.8%), Presbyterianism (5.5%) and "Christian not further defined" (i.e. people identifying as Christian but not stating the denomination, 6.6%). The Māori-based Ringatū and Rātana religions (1.3%) are also Christian in origin.[284][285] Immigration and demographic change in recent decades has contributed to the growth of minority religions,[286] such as Hinduism (2.6%), Buddhism (1.1%), Islam (1.3%) and Sikhism (0.5%).[284] The Auckland Region exhibited the greatest religious diversity.[284] +

      +

      + Education +

      + +

      + Primary and secondary schooling is compulsory for children aged 6 to 16, with the majority attending from the age of 5.[287] There are 13 school years and attending state (public) schools is free to New Zealand citizens and permanent residents from a person's 5th birthday to the end of the calendar year following their 19th birthday.[288] New Zealand has an adult literacy rate of 99%,[143] and over half of the population aged 15 to 29 hold a tertiary qualification.[287] There are five types of government-owned tertiary institutions: universities, colleges of education, polytechnics, specialist colleges, and wānanga,[289] in addition to private training establishments.[290] In the adult population 14.2% have a bachelor's degree or higher, 30.4% have some form of secondary qualification as their highest qualification and 22.4% have no formal qualification.[291] The OECD's Programme for International Student Assessment ranks New Zealand's education system as the seventh best in the world, with students performing exceptionally well in reading, mathematics and science.[292] +

      + +

      + Culture +

      + +
      +

      Tall wooden carving showing Kupe above two tentacled sea creatures +

      +
      +

      Late 20th-century house-post depicting the navigator Kupe fighting two sea creatures +

      +
      +

      + Early Māori adapted the tropically based east Polynesian culture in line with the challenges associated with a larger and more diverse environment, eventually developing their own distinctive culture. Social organisation was largely communal with families (whānau), subtribes (hapū) and tribes (iwi) ruled by a chief (rangatira), whose position was subject to the community's approval.[293] The British and Irish immigrants brought aspects of their own culture to New Zealand and also influenced Māori culture,[294][295] particularly with the introduction of Christianity.[296] However, Māori still regard their allegiance to tribal groups as a vital part of their identity, and Māori kinship roles resemble those of other Polynesian peoples.[297] More recently American, Australian, Asian and other European cultures have exerted influence on New Zealand. Non-Māori Polynesian cultures are also apparent, with Pasifika, the world's largest Polynesian festival, now an annual event in Auckland.[298] +

      +

      + The largely rural life in early New Zealand led to the image of New Zealanders being rugged, industrious problem solvers.[299] Modesty was expected and enforced through the "tall poppy syndrome", where high achievers received harsh criticism.[300] At the time New Zealand was not known as an intellectual country.[301] From the early 20th century until the late 1960s, Māori culture was suppressed by the attempted assimilation of Māori into British New Zealanders.[274] In the 1960s, as tertiary education became more available and cities expanded[302] urban culture began to dominate.[303] However, rural imagery and themes are common in New Zealand's art, literature and media.[304] +

      +

      + New Zealand's national symbols are influenced by natural, historical, and Māori sources. The silver fern is an emblem appearing on army insignia and sporting team uniforms.[305] Certain items of popular culture thought to be unique to New Zealand are called "Kiwiana".[305] +

      +

      + Art +

      + +

      + As part of the resurgence of Māori culture, the traditional crafts of carving and weaving are now more widely practised and Māori artists are increasing in number and influence.[306] Most Māori carvings feature human figures, generally with three fingers and either a natural-looking, detailed head or a grotesque head.[307] Surface patterns consisting of spirals, ridges, notches and fish scales decorate most carvings.[308] The pre-eminent Māori architecture consisted of carved meeting houses (wharenui) decorated with symbolic carvings and illustrations. These buildings were originally designed to be constantly rebuilt, changing and adapting to different whims or needs.[309] +

      +

      + Māori decorated the white wood of buildings, canoes and cenotaphs using red (a mixture of red ochre and shark fat) and black (made from soot) paint and painted pictures of birds, reptiles and other designs on cave walls.[310] Māori tattoos (moko) consisting of coloured soot mixed with gum were cut into the flesh with a bone chisel.[311] Since European arrival paintings and photographs have been dominated by landscapes, originally not as works of art but as factual portrayals of New Zealand.[312] Portraits of Māori were also common, with early painters often portraying them as "noble savages", exotic beauties or friendly natives.[312] The country's isolation delayed the influence of European artistic trends allowing local artists to develop their own distinctive style of regionalism.[313] During the 1960s and 1970s many artists combined traditional Māori and Western techniques, creating unique art forms.[314] New Zealand art and craft has gradually achieved an international audience, with exhibitions in the Venice Biennale in 2001 and the "Paradise Now" exhibition in New York in 2004.[306][315] +

      +
      +

      Refer to caption

      +
      +

      + Māori cloaks are made of fine flax fibre and patterned with black, red and white triangles, diamonds and other geometric shapes.[316] Greenstone was fashioned into earrings and necklaces, with the most well-known design being the hei-tiki, a distorted human figure sitting cross-legged with its head tilted to the side.[317] Europeans brought English fashion etiquette to New Zealand, and until the 1950s most people dressed up for social occasions.[318] Standards have since relaxed and New Zealand fashion has received a reputation for being casual, practical and lacklustre.[319][320] However, the local fashion industry has grown significantly since 2000, doubling exports and increasing from a handful to about 50 established labels, with some labels gaining international recognition.[320] +

      +

      + Literature +

      + +

      + Māori quickly adopted writing as a means of sharing ideas, and many of their oral stories and poems were converted to the written form.[321] Most early English literature was obtained from Britain and it was not until the 1950s when local publishing outlets increased that New Zealand literature started to become widely known.[322] Although still largely influenced by global trends (modernism) and events (the Great Depression), writers in the 1930s began to develop stories increasingly focused on their experiences in New Zealand. During this period literature changed from a journalistic activity to a more academic pursuit.[323] Participation in the world wars gave some New Zealand writers a new perspective on New Zealand culture and with the post-war expansion of universities local literature flourished.[324] Dunedin is a UNESCO City of Literature.[325] +

      +

      + Media and entertainment +

      + +

      + New Zealand music has been influenced by blues, jazz, country, rock and roll and hip hop, with many of these genres given a unique New Zealand interpretation.[326] Māori developed traditional chants and songs from their ancient Southeast Asian origins, and after centuries of isolation created a unique "monotonous" and "doleful" sound.[327] Flutes and trumpets were used as musical instruments[328] or as signalling devices during war or special occasions.[329] Early settlers brought over their ethnic music, with brass bands and choral music being popular, and musicians began touring New Zealand in the 1860s.[330][331] Pipe bands became widespread during the early 20th century.[332] The New Zealand recording industry began to develop from 1940 onwards and many New Zealand musicians have obtained success in Britain and the United States.[326] Some artists release Māori language songs and the Māori tradition-based art of kapa haka (song and dance) has made a resurgence.[333] The New Zealand Music Awards are held annually by Recorded Music NZ; the awards were first held in 1965 by Reckitt & Colman as the Loxene Golden Disc awards.[334] Recorded Music NZ also publishes the country's official weekly record charts.[335] +

      +
      +

      Hills with inset, round doors. Reflected in water.

      +
      +

      + Public radio was introduced in New Zealand in 1922.[337] A state-owned television service began in 1960.[338] Deregulation in the 1980s saw a sudden increase in the numbers of radio and television stations.[339] New Zealand television primarily broadcasts American and British programming, along with a large number of Australian and local shows.[340] The number of New Zealand films significantly increased during the 1970s. In 1978 the New Zealand Film Commission started assisting local film-makers and many films attained a world audience, some receiving international acknowledgement.[339] The highest-grossing New Zealand films are Hunt for the Wilderpeople, Boy, The World's Fastest Indian, Once Were Warriors and Whale Rider.[341] The country's diverse scenery and compact size, plus government incentives,[342] have encouraged some producers to shoot big-budget productions in New Zealand, including Avatar, The Lord of the Rings, The Hobbit, The Chronicles of Narnia, King Kong and The Last Samurai.[343] The New Zealand media industry is dominated by a small number of companies, most of which are foreign-owned, although the state retains ownership of some television and radio stations.[344] Since 1994, Freedom House has consistently ranked New Zealand's press freedom in the top twenty, with the 19th freest media in 2015.[345] +

      + +

      + Sports +

      + +
      +

      Rugby team wearing all black, facing the camera, knees bent, and facing toward a team wearing white

      +
      +

      + Most of the major sporting codes played in New Zealand have British origins.[346] Rugby union is considered the national sport[347] and attracts the most spectators.[348] Golf, netball, tennis and cricket have the highest rates of adult participation, while netball, rugby union and football (soccer) are particularly popular among young people.[348][349] Around 54% of New Zealand adolescents participate in sports for their school.[349] Victorious rugby tours to Australia and the United Kingdom in the late 1880s and the early 1900s played an early role in instilling a national identity.[350] Horseracing was also a popular spectator sport and became part of the "Rugby, Racing and Beer" culture during the 1960s.[351] Māori participation in European sports was particularly evident in rugby and the country's team performs a haka, a traditional Māori challenge, before international matches.[352] New Zealand is known for its extreme sports, adventure tourism[353] and strong mountaineering tradition, as seen in the success of notable New Zealander Sir Edmund Hillary.[354][355] Other outdoor pursuits such as cycling, fishing, swimming, running, tramping, canoeing, hunting, snowsports, surfing and sailing are also popular.[356] The Polynesian sport of waka ama racing has experienced a resurgence of interest in New Zealand since the 1980s.[357] +

      +

      + New Zealand has competitive international teams in rugby union, rugby league, netball, cricket, softball, and sailing. New Zealand participated at the Summer Olympics in 1908 and 1912 as a joint team with Australia, before first participating on its own in 1920.[358] The country has ranked highly on a medals-to-population ratio at recent Games.[359][360] The "All Blacks", the national rugby union team, are the most successful in the history of international rugby[361] and the reigning World Cup champions.[362] +

      +

      + Cuisine +

      + +
      +

      Raw meat and vegetables

      +

      Ingredients to be prepared for a hāngi +

      +
      +

      + The national cuisine has been described as Pacific Rim, incorporating the native Māori cuisine and diverse culinary traditions introduced by settlers and immigrants from Europe, Polynesia and Asia.[363] New Zealand yields produce from land and sea—most crops and livestock, such as maize, potatoes and pigs, were gradually introduced by the early European settlers.[364] Distinctive ingredients or dishes include lamb, salmon, kōura (crayfish),[365] dredge oysters, whitebait, pāua (abalone), mussels, scallops, pipis and tuatua (both are types of New Zealand shellfish),[366] kūmara (sweet potato), kiwifruit, tamarillo and pavlova (considered a national dish).[367][363] A hāngi is a traditional Māori method of cooking food using heated rocks buried in a pit oven. After European colonisation, Māori began cooking with pots and ovens and the hāngi was used less frequently, although it is still used for formal occasions such as tangihanga.[368] +

      + +

      + See also +

      + + + +

      + Footnotes +

      +
      +
        +
      1. + ^ "God Save the Queen" is officially a national anthem but is generally used only on regal and viceregal occasions.[1] +
      2. +
      3. + ^ English is a de facto official language due to its widespread use.[2] +
      4. +
      5. + ^ a b Ethnicity figures add to more than 100% as people could choose more than one ethnic group. +
      6. +
      7. + ^ The proportion of New Zealand's area (excluding estuaries) covered by rivers, lakes and ponds, based on figures from the New Zealand Land Cover Database,[4] is (357526 + 81936) / (26821559 – 92499–26033 – 19216) = 1.6%. If estuarine open water, mangroves, and herbaceous saline vegetation are included, the figure is 2.2%. +
      8. +
      9. + ^ The Chatham Islands have a separate time zone, 45 minutes ahead of the rest of New Zealand. +
      10. +
      11. + ^ Clocks are advanced by an hour from the last Sunday in September until the first Sunday in April.[9] Daylight saving time is also observed in the Chatham Islands, 45 minutes ahead of NZDT. +
      12. +
      13. + ^ A person born on or after 1 January 2006 acquires New Zealand citizenship at birth only if at least one parent is a New Zealand citizen or permanent resident. People born on or before 31 December 2005 acquired citizenship at birth (jus soli).[137] +
      14. +
      15. + ^ The population is increasing at a rate of 1.4–2.0% per year and is projected to rise to 5.01–5.51 million in 2025.[246] +
      16. +
      17. + ^ In 2015, 55% of Māori adults (aged 15 years and over) reported knowledge of te reo Māori. Of these speakers, 64% use Māori at home and 50,000 can speak the language "very well" or "well".[277] +
      18. +
      19. + ^ Of the 86,403 people that replied they spoke Samoan, 51,336 lived in the Auckland Region. +
      20. +
      21. + ^ Religion percentages may not add to 100% as people could claim multiple religions or object to answering the question. +
      22. +
      +
      +

      + Citations +

      +
      +
        +
      1. + ^ "Protocol for using New Zealand's National Anthems". Ministry for Culture and Heritage. Retrieved 17 February 2008. +
      2. +
      3. + ^ New Zealand Government (21 December 2007). International Covenant on Civil and Political Rights Fifth Periodic Report of the Government of New Zealand (PDF) (Report). p. 89. Archived from the original (PDF) on 24 January 2015. Retrieved 18 November 2015. In addition to the Māori language, New Zealand Sign Language is also an official language of New Zealand. The New Zealand Sign Language Act 2006 permits the use of NZSL in legal proceedings, facilitates competency standards for its interpretation and guides government departments in its promotion and use. English, the medium for teaching and learning in most schools, is a de facto official language by virtue of its widespread use. For these reasons, these three languages have special mention in the New Zealand Curriculum. + +
      4. +
      5. + ^ "2018 Census population and dwelling counts". Statistics New Zealand. Retrieved 26 September 2019. + +
      6. +
      7. + ^ "The New Zealand Land Cover Database". New Zealand Land Cover Database 2. Ministry for the Environment. 1 July 2009. Retrieved 26 April 2011. + +
      8. +
      9. + ^ a b "Population clock". Statistics New Zealand. Retrieved 14 April 2016. + The population estimate shown is automatically calculated daily at 00:00 UTC and is based on data obtained from the population clock on the date shown in the citation. +
      10. +
      11. + ^ a b c d e "New Zealand". International Monetary Fund. Retrieved 9 October 2018. + +
      12. +
      13. + ^ "Income inequality". Statistics New Zealand. Retrieved 14 June 2015. + +
      14. +
      15. + ^ a b "Human Development Report 2018" (PDF). HDRO (Human Development Report Office) United Nations Development Programme. p. 22. Retrieved 14 September 2018. + +
      16. +
      17. + ^ "New Zealand Daylight Time Order 2007 (SR 2007/185)". New Zealand Parliamentary Counsel Office. 6 July 2007. Retrieved 6 March 2017. + +
      18. +
      19. + ^ There is no official all-numeric date format for New Zealand, but government recommendations generally follow Australian date and time notation. See "The Govt.nz style guide", New Zealand Government, 9 December 2016, retrieved 7 March 2019 + . +
      20. +
      21. + ^ Tasman, Abel. "JOURNAL or DESCRIPTION By me Abel Jansz Tasman, Of a Voyage from Batavia for making Discoveries of the Unknown South Land in the year 1642". Project Gutenberg Australia. Retrieved 26 March 2018. + +
      22. +
      23. + ^ Wilson, John (March 2009). "European discovery of New Zealand – Tasman's achievement". Te Ara: The Encyclopedia of New Zealand. Retrieved 24 January 2011. + +
      24. +
      25. + ^ John Bathgate. "The Pamphlet Collection of Sir Robert Stout:Volume 44. Chapter 1, Discovery and Settlement". NZETC. Retrieved 17 August 2018. He named the country Staaten Land, in honour of the States-General of Holland, in the belief that it was part of the great southern continent. + +
      26. +
      27. + ^ Wilson, John (September 2007). "Tasman's achievement". Te Ara: The Encyclopedia of New Zealand. Retrieved 16 February 2008. + +
      28. +
      29. + ^ Mackay, Duncan (1986). "The Search For The Southern Land". In Fraser, B (ed.). The New Zealand Book Of Events. Auckland: Reed Methuen. pp. 52–54. + +
      30. +
      31. + ^ a b McKinnon, Malcolm (November 2009). "Place names – Naming the country and the main islands". Te Ara: The Encyclopedia of New Zealand. Retrieved 24 January 2011. + +
      32. +
      33. + ^ King 2003, p. 41. +
      34. +
      35. + ^ Hay, Maclagan & Gordon 2008, p. 72. +
      36. +
      37. + ^ a b Mein Smith 2005, p. 6. +
      38. +
      39. + ^ Brunner, Thomas (1851). The Great Journey: an expedition to explore the interior of the Middle Island, New Zealand, 1846-8. Royal Geographical Society. + +
      40. +
      41. + ^ a b Williamson, Maurice (10 October 2013). "Names of NZ's two main islands formalised" (Press release). New Zealand Government. Retrieved 1 May 2017. + +
      42. +
      43. + ^ Wilmshurst, J. M.; Hunt, T. L.; Lipo, C. P.; Anderson, A. J. (2010). "High-precision radiocarbon dating shows recent and rapid initial human colonization of East Polynesia". Proceedings of the National Academy of Sciences. 108 (5): 1815. Bibcode:2011PNAS..108.1815W. doi:10.1073/pnas.1015876108. PMC 3033267. PMID 21187404. + +
      44. +
      45. + ^ McGlone, M.; Wilmshurst, J. M. (1999). "Dating initial Maori environmental impact in New Zealand". Quaternary International. 59: 5–16. Bibcode:1999QuInt..59....5M. doi:10.1016/S1040-6182(98)00067-6. + +
      46. +
      47. + ^ Murray-McIntosh, Rosalind P.; Scrimshaw, Brian J.; Hatfield, Peter J.; Penny, David (1998). "Testing migration patterns and estimating founding population size in Polynesia by using human mtDNA sequences". Proceedings of the National Academy of Sciences of the United States of America. 95 (15): 9047–52. Bibcode:1998PNAS...95.9047M. doi:10.1073/pnas.95.15.9047. PMC 21200. + +
      48. +
      49. + ^ Wilmshurst, J. M.; Anderson, A. J.; Higham, T. F. G.; Worthy, T. H. (2008). "Dating the late prehistoric dispersal of Polynesians to New Zealand using the commensal Pacific rat". Proceedings of the National Academy of Sciences. 105 (22): 7676. Bibcode:2008PNAS..105.7676W. doi:10.1073/pnas.0801507105. PMC 2409139. PMID 18523023. + +
      50. +
      51. + ^ Moodley, Y.; Linz, B.; Yamaoka, Y.; Windsor, H.M.; Breurec, S.; Wu, J.-Y.; Maady, A.; Bernhöft, S.; Thiberge, J.-M.; et al. (2009). "The Peopling of the Pacific from a Bacterial Perspective". Science. 323 (5913): 527–530. Bibcode:2009Sci...323..527M. doi:10.1126/science.1166083. PMC 2827536. PMID 19164753. + +
      52. +
      53. + ^ Ballara, Angela (1998). Iwi: The Dynamics of Māori Tribal Organisation from c. 1769 to c. 1945 (1st ed.). Wellington: Victoria University Press. ISBN 9780864733283. + +
      54. +
      55. + ^ Clark, Ross (1994). "Moriori and Māori: The Linguistic Evidence". In Sutton, Douglas (ed.). The Origins of the First New Zealanders. Auckland: Auckland University Press. pp. 123–135. + +
      56. +
      57. + ^ Davis, Denise (September 2007). "The impact of new arrivals". Te Ara: The Encyclopedia of New Zealand. Retrieved 30 April 2010. + +
      58. +
      59. + ^ Davis, Denise; Solomon, Māui (March 2009). "'Moriori – The impact of new arrivals'". Te Ara: The Encyclopedia of New Zealand. Retrieved 23 March 2011. + +
      60. +
      61. + ^ a b Mein Smith 2005, p. 23. +
      62. +
      63. + ^ Salmond, Anne. Two Worlds: First Meetings Between Maori and Europeans 1642–1772. Auckland: Penguin Books. p. 82. ISBN 0-670-83298-7. + +
      64. +
      65. + ^ King 2003, p. 122. +
      66. +
      67. + ^ Fitzpatrick, John (2004). "Food, warfare and the impact of Atlantic capitalism in Aotearo/New Zealand" (PDF). Australasian Political Studies Association Conference: APSA 2004 Conference Papers. Archived from the original (PDF) on 11 May 2011. + +
      68. +
      69. + ^ Brailsford, Barry (1972). Arrows of Plague. Wellington: Hick Smith and Sons. p. 35. ISBN 0-456-01060-2. + +
      70. +
      71. + ^ Wagstrom, Thor (2005). "Broken Tongues and Foreign Hearts". In Brock, Peggy (ed.). Indigenous Peoples and Religious Change. Boston: Brill Academic Publishers. pp. 71 and 73. ISBN 978-90-04-13899-5. + +
      72. +
      73. + ^ Lange, Raeburn (1999). May the people live: a history of Māori health development 1900–1920. Auckland University Press. p. 18. ISBN 978-1-86940-214-3. + +
      74. +
      75. + ^ "A Nation sub-divided". Australian Heritage. Heritage Australia Publishing. 2011. Archived from the original on 28 February 2015. Retrieved 27 December 2014. + +
      76. +
      77. + ^ a b Rutherford, James (April 2009) [originally published in 1966]. McLintock, Alexander (ed.). Busby, James. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      78. +
      79. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Sir George Gipps. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      80. +
      81. + ^ a b Wilson, John (March 2009). "Government and nation – The origins of nationhood". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 January 2011. + +
      82. +
      83. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Settlement from 1840 to 1852. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      84. +
      85. + ^ Foster, Bernard (April 2009) [originally published in 1966]. McLintock, Alexander (ed.). Akaroa, French Settlement At. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      86. +
      87. + ^ Simpson, K (September 2010). "Hobson, William – Biography". In McLintock, Alexander (ed.). Dictionary of New Zealand Biography. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      88. +
      89. + ^ Phillips, Jock (April 2010). "British immigration and the New Zealand Company". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 January 2011. + +
      90. +
      91. + ^ "Crown colony era – the Governor-General". Ministry for Culture and Heritage. March 2009. Retrieved 7 January 2011. + +
      92. +
      93. + ^ "New Zealand's 19th-century wars – overview". Ministry for Culture and Heritage. April 2009. Retrieved 7 January 2011. + +
      94. +
      95. + ^ a b c d Wilson, John (March 2009). "Government and nation – The constitution". Te Ara: The Encyclopedia of New Zealand. Retrieved 2 February 2011. + See pages 2 and 3. +
      96. +
      97. + ^ Temple, Philip (1980). Wellington Yesterday. John McIndoe. ISBN 0-86868-012-5. + +
      98. +
      99. + ^ "Parliament moves to Wellington". Ministry for Culture and Heritage. January 2017. Retrieved 27 April 2017. + +
      100. +
      101. + ^ a b Wilson, John (March 2009). "History – Liberal to Labour". Te Ara: The Encyclopedia of New Zealand. Retrieved 27 April 2017. + +
      102. +
      103. + ^ Hamer, David. "Seddon, Richard John". Dictionary of New Zealand Biography. Ministry for Culture and Heritage. Retrieved 27 April 2017. + +
      104. +
      105. + ^ Boxall, Peter; Haynes, Peter (1997). "Strategy and Trade Union Effectiveness in a Neo-liberal Environment". British Journal of Industrial Relations. 35 (4): 567–591. doi:10.1111/1467-8543.00069. Archived from the original (PDF) on 11 May 2011. + +
      106. +
      107. + ^ "Proclamation". The London Gazette. No. 28058. 10 September 1907. p. 6149. + +
      108. +
      109. + ^ "Dominion status – Becoming a dominion". Ministry for Culture and Heritage. September 2014. Retrieved 26 April 2017. + +
      110. +
      111. + ^ "War and Society". Ministry for Culture and Heritage. Retrieved 7 January 2011. + +
      112. +
      113. + ^ Easton, Brian (April 2010). "Economic history – Interwar years and the great depression". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 January 2011. + +
      114. +
      115. + ^ Derby, Mark (May 2010). "Strikes and labour disputes – Wars, depression and first Labour government". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 February 2011. + +
      116. +
      117. + ^ Easton, Brian (November 2010). "Economic history – Great boom, 1935–1966". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 February 2011. + +
      118. +
      119. + ^ Keane, Basil (November 2010). "Te Māori i te ohanga – Māori in the economy – Urbanisation". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 January 2011. + +
      120. +
      121. + ^ Royal, Te Ahukaramū (March 2009). "Māori – Urbanisation and renaissance". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 February 2011. + +
      122. +
      123. + ^ Healing the past, building a future: A Guide to Treaty of Waitangi Claims and Negotiations with the Crown (PDF). Office of Treaty Settlements. March 2015. ISBN 978-0-478-32436-5. Retrieved 26 April 2017. + +
      124. +
      125. + ^ Report on the Crown's Foreshore and Seabed Policy (Report). Ministry of Justice. Retrieved 26 April 2017. + +
      126. +
      127. + ^ Barker, Fiona (June 2012). "Debate about the foreshore and seabed". Te Ara: The Encyclopedia of New Zealand. Retrieved 26 April 2017. + +
      128. +
      129. + ^ a b "New Zealand's Constitution". The Governor-General of New Zealand. Retrieved 13 January 2010. + +
      130. +
      131. + ^ a b c "Factsheet – New Zealand – Political Forces". The Economist. The Economist Group. 15 February 2005. Archived from the original on 14 May 2006. Retrieved 4 August 2009. + +
      132. +
      133. + ^ "Royal Titles Act 1974". New Zealand Parliamentary Counsel Office. February 1974. Section 1. Retrieved 8 January 2011. + +
      134. +
      135. + ^ "Constitution Act 1986". New Zealand Parliamentary Counsel Office. 1 January 1987. Section 2.1. Retrieved 15 July 2018. The Sovereign in right of New Zealand is the head of State of New Zealand, and shall be known by the royal style and titles proclaimed from time to time. + +
      136. +
      137. + ^ "The Role of the Governor-General". The Governor-General of New Zealand. Retrieved 6 July 2017. + +
      138. +
      139. + ^ Harris, Bruce (2009). "Replacement of the Royal Prerogative in New Zealand". New Zealand Universities Law Review. 23: 285–314. Archived from the original on 18 July 2011. Retrieved 28 August 2016. + +
      140. +
      141. + ^ a b "The Reserve Powers". The Governor-General of New Zealand. Retrieved 8 January 2011. + +
      142. +
      143. + ^ a b c d "Parliament Brief: What is Parliament?". New Zealand Parliament. Retrieved 30 November 2016. + +
      144. +
      145. + ^ McLean, Gavin (February 2015). "Premiers and prime ministers". Te Ara: The Encyclopedia of New Zealand. Retrieved 30 November 2016. + +
      146. +
      147. + ^ Wilson, John (November 2010). "Government and nation – System of government". Te Ara: The Encyclopedia of New Zealand. Retrieved 9 January 2011. + +
      148. +
      149. + ^ "Principles of Cabinet decision making". Cabinet Manual. Department of the Prime Minister and Cabinet. 2008. Retrieved 1 December 2016. + +
      150. +
      151. + ^ "The electoral cycle". Cabinet Manual. Department of the Prime Minister and Cabinet. 2008. Retrieved 30 April 2017. + +
      152. +
      153. + ^ a b "First past the post – the road to MMP". Ministry for Culture and Heritage. September 2009. Retrieved 9 January 2011. + +
      154. +
      155. + ^ "Reviewing electorate numbers and boundaries". Electoral Commission. 8 May 2005. Archived from the original on 9 November 2011. Retrieved 7 July 2018. + +
      156. +
      157. + ^ "Sainte-Laguë allocation formula". Electoral Commission. 4 February 2013. Retrieved 31 May 2014. + +
      158. +
      159. + ^ Paxton, Pamela; Hughes, Melanie M. (2015). Women, Politics, and Power: A Global Perspective. CQ Press. p. 107. ISBN 978-1-48-337701-8. Retrieved 25 July 2017. + +
      160. +
      161. + ^ "Jacinda Ardern sworn in as new Prime Minister". New Zealand Herald. 26 October 2017. Retrieved 26 October 2017. + +
      162. +
      163. + ^ "Female political leaders have been smashing glass ceilings for ages". Stuff.co.nz. Fairfax NZ. 27 October 2017. Retrieved 19 July 2018. + +
      164. +
      165. + ^ "Role of the Chief Justice". Courts of New Zealand. Retrieved 9 June 2018. + +
      166. +
      167. + ^ "Structure of the court system". Courts of New Zealand. Retrieved 9 June 2018. + +
      168. +
      169. + ^ "The Judiciary". Ministry of Justice. Archived from the original on 24 November 2010. Retrieved 9 January 2011. + +
      170. +
      171. + ^ "The Fragile States Index 2016". The Fund for Peace. Archived from the original on 4 February 2017. Retrieved 30 November 2016. + +
      172. +
      173. + ^ "Democracy Index 2017" (PDF). Economist Intelligence Unit. 2018. p. 5. Retrieved 9 December 2018. + +
      174. +
      175. + ^ "Corruption Perceptions Index 2017". Transparency International. 21 February 2018. Retrieved 9 December 2018. + +
      176. +
      177. + ^ "New Zealand". Country Reports on Human Rights Practices for 2017. United States Department of State. Retrieved 9 December 2018. + +
      178. +
      179. + ^ "New Zealand". OECD Better Life Index. 2016. Retrieved 30 November 2016. + +
      180. +
      181. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. External Relations. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      182. +
      183. + ^ "Michael Joseph Savage". Ministry for Culture and Heritage. July 2010. Retrieved 29 January 2011. + +
      184. +
      185. + ^ Patman, Robert (2005). "Globalisation, Sovereignty, and the Transformation of New Zealand Foreign Policy" (PDF). Working Paper 21/05. Centre for Strategic Studies, Victoria University of Wellington. p. 8. Archived from the original (PDF) on 25 September 2007. Retrieved 12 March 2007. + +
      186. +
      187. + ^ "Department Of External Affairs: Security Treaty between Australia, New Zealand and the United States of America". Australian Government. September 1951. Archived from the original on 29 June 2011. Retrieved 11 January 2011. + +
      188. +
      189. + ^ "The Vietnam War". New Zealand History. Ministry for Culture and Heritage. June 2008. Retrieved 11 January 2011. + +
      190. +
      191. + ^ "Sinking the Rainbow Warrior – nuclear-free New Zealand". New Zealand History. Ministry for Culture and Heritage. August 2008. Retrieved 11 January 2011. + +
      192. +
      193. + ^ "Nuclear-free legislation – nuclear-free New Zealand". New Zealand History. Ministry for Culture and Heritage. August 2008. Retrieved 11 January 2011. + +
      194. +
      195. + ^ Lange, David (1990). Nuclear Free: The New Zealand Way. New Zealand: Penguin Books. ISBN 0-14-014519-2. + +
      196. +
      197. + ^ "Australia in brief". Australian Department of Foreign Affairs and Trade. Archived from the original on 22 December 2010. Retrieved 11 January 2011. + +
      198. +
      199. + ^ a b "New Zealand country brief". Australian Department of Foreign Affairs and Trade. Retrieved 11 January 2011. + +
      200. +
      201. + ^ Collett, John (4 September 2013). "Kiwis face hurdles in pursuit of lost funds". Retrieved 4 October 2013. + +
      202. +
      203. + ^ Bertram, Geoff (April 2010). "South Pacific economic relations – Aid, remittances and tourism". Te Ara: The Encyclopedia of New Zealand. Retrieved 11 January 2011. + +
      204. +
      205. + ^ Howes, Stephen (November 2010). "Making migration work: Lessons from New Zealand". Development Policy Centre. Retrieved 23 March 2011. + +
      206. +
      207. + ^ Ayele, Yoseph (28 September 2017). "The Growing Momentum for Global Impact in New Zealand". Edmund Hillary Fellowship. Retrieved 9 July 2019. + +
      208. +
      209. + ^ "Member States of the United Nations". United Nations. Retrieved 11 January 2011. + +
      210. +
      211. + ^ "New Zealand". The Commonwealth. Retrieved 1 December 2016. + +
      212. +
      213. + ^ "Members and partners". Organisation for Economic Co-operation and Development. Retrieved 11 January 2011. + +
      214. +
      215. + ^ "The future of the Five Power Defence Arrangements". The Strategist. 8 November 2012. Retrieved 1 December 2016. + +
      216. +
      217. + ^ "About Us: Role and Responsibilities". New Zealand Defence Force. Retrieved 11 January 2011. + +
      218. +
      219. + ^ Ayson, Robert (2007). "New Zealand Defence and Security Policy,1990–2005". In Alley, Roderic (ed.). New Zealand In World Affairs, Volume IV: 1990–2005. Wellington: Victoria University Press. p. 132. ISBN 978-0-86473-548-5. + +
      220. +
      221. + ^ "The Battle for Crete". New Zealand History. Ministry for Culture and Heritage. May 2010. Retrieved 9 January 2011. + +
      222. +
      223. + ^ "El Alamein – The North African Campaign". New Zealand History. Ministry for Culture and Heritage. May 2009. Retrieved 9 January 2011. + +
      224. +
      225. + ^ Holmes, Richard (September 2010). "World War Two: The Battle of Monte Cassino". Retrieved 9 January 2011. + +
      226. +
      227. + ^ "Gallipoli stirred new sense of national identity says Clark". New Zealand Herald. April 2005. Retrieved 9 January 2011. + +
      228. +
      229. + ^ Prideaux, Bruce (2007). Ryan, Chris (ed.). Battlefield tourism: history, place and interpretation. Elsevier Science. p. 18. ISBN 978-0-08-045362-0. + +
      230. +
      231. + ^ Burke, Arthur. "The Spirit of ANZAC". ANZAC Day Commemoration Committee. Archived from the original on 26 December 2010. Retrieved 11 January 2011. + +
      232. +
      233. + ^ "South African War 1899–1902". Ministry for Culture and Heritage. February 2009. Retrieved 11 January 2011. + +
      234. +
      235. + ^ "New Zealand in the Korean War". New Zealand History. Ministry for Culture and Heritage. Retrieved 1 December 2016. + +
      236. +
      237. + ^ "NZ and the Malayan Emergency". Ministry for Culture and Heritage. August 2010. Retrieved 11 January 2011. + +
      238. +
      239. + ^ "New Zealand Defence Force Overseas Operations". New Zealand Defence Force. January 2008. Archived from the original on 25 January 2008. Retrieved 17 February 2008. + +
      240. +
      241. + ^ a b "New Zealand's Nine Provinces (1853–76)" (PDF). Friends of the Hocken Collections. University of Otago. March 2000. Retrieved 13 January 2011. + +
      242. +
      243. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Provincial Divergencies. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      244. +
      245. + ^ Swarbrick, Nancy (September 2016). "Public holidays". Te Ara: The Encyclopedia of New Zealand. Retrieved 25 June 2017. + +
      246. +
      247. + ^ "Overview – regional rugby". Ministry for Culture and Heritage. September 2010. Retrieved 13 January 2011. + +
      248. +
      249. + ^ Dollery, Brian; Keogh, Ciaran; Crase, Lin (2007). "Alternatives to Amalgamation in Australian Local Government: Lessons from the New Zealand Experience" (PDF). Sustaining Regions. 6 (1): 50–69. Archived from the original (PDF) on 29 August 2007. + +
      250. +
      251. + ^ a b c Sancton, Andrew (2000). Merger mania: the assault on local government. McGill-Queen's University Press. p. 84. ISBN 0-7735-2163-1. + +
      252. +
      253. + ^ "Subnational population estimates at 30 June 2010 (boundaries at 1 November 2010)". Statistics New Zealand. 26 October 2010. Archived from the original on 10 June 2011. Retrieved 2 April 2011. + +
      254. +
      255. + ^ Smelt & Jui Lin 2009, p. 33. +
      256. +
      257. + ^ a b "Glossary". Department of Internal Affairs. Retrieved 28 August 2016. + +
      258. +
      259. + ^ "Chatham Islands Council Act 1995 No 41". New Zealand Parliamentary Counsel Office. 29 July 1995. Retrieved 8 August 2017. + +
      260. +
      261. + ^ Gimpel, Diane (2011). Monarchies. ABDO Publishing Company. p. 22. ISBN 978-1-617-14792-0. Retrieved 18 November 2016. + +
      262. +
      263. + ^ "System of Government". Government of Niue. Archived from the original on 13 November 2010. Retrieved 13 January 2010. + +
      264. +
      265. + ^ "Government – Structure, Personnel". Government of the Cook Islands. Retrieved 13 January 2010. + +
      266. +
      267. + ^ "Tokelau Government". Government of Tokelau. Retrieved 16 November 2016. + +
      268. +
      269. + ^ "Scott Base". Antarctica New Zealand. Retrieved 13 January 2010. + +
      270. +
      271. + ^ "Citizenship Act 1977 No 61". Zealand Parliamentary Counsel Office. 1 December 1977. Retrieved 26 May 2017. + +
      272. +
      273. + ^ "Check if you're a New Zealand citizen". Department of Internal Affairs. Retrieved 20 January 2015. + +
      274. +
      275. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. The Sea Floor. An Encyclopaedia of New Zealand. Retrieved 13 January 2011. + +
      276. +
      277. + ^ "Hauraki Gulf islands". Auckland City Council. Archived from the original on 25 December 2010. Retrieved 13 January 2011. + +
      278. +
      279. + ^ Hindmarsh (2006). "Discovering D'Urville". Heritage New Zealand. Archived from the original on 11 May 2011. Retrieved 13 January 2011. + +
      280. +
      281. + ^ "Distance tables". Auckland Coastguard. Archived from the original on 23 January 2011. Retrieved 2 March 2011. + +
      282. +
      283. + ^ McKenzie, D. W. (1987). Heinemann New Zealand atlas. Heinemann Publishers. ISBN 0-7900-0187-X. + +
      284. +
      285. + ^ a b c d e f "CIA – The World Factbook". Cia.gov. Retrieved 4 May 2013. + +
      286. +
      287. + ^ "Geography". Statistics New Zealand. 1999. Archived from the original on 22 May 2010. Retrieved 21 December 2009. + +
      288. +
      289. + ^ Offshore Options: Managing Environmental Effects in New Zealand's Exclusive Economic Zone (PDF). Wellington: Ministry for the Environment. 2005. ISBN 0-478-25916-6. Retrieved 23 June 2017. + +
      290. +
      291. + ^ Coates, Glen (2002). The rise and fall of the Southern Alps. Canterbury University Press. p. 15. ISBN 0-908812-93-0. + +
      292. +
      293. + ^ Garden 2005, p. 52. +
      294. +
      295. + ^ Grant, David (March 2009). "Southland places – Fiordland's coast". Te Ara: The Encyclopedia of New Zealand. Retrieved 14 January 2011. + +
      296. +
      297. + ^ "Central North Island volcanoes". Department of Conservation. Archived from the original on 29 December 2010. Retrieved 14 January 2011. + +
      298. +
      299. + ^ Walrond, Carl (March 2009). "Natural environment – Geography and geology". Te Ara: The Encyclopedia of New Zealand. Retrieved 14 January 2010. + +
      300. +
      301. + ^ "Taupo". GNS Science. Archived from the original on 24 March 2011. Retrieved 2 April 2011. + +
      302. +
      303. + ^ a b Lewis, Keith; Nodder, Scott; Carter, Lionel (March 2009). "Sea floor geology – Active plate boundaries". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      304. +
      305. + ^ Wallis, G. P.; Trewick, S. A. (2009). "New Zealand phylogeography: evolution on a small continent". Molecular Ecology. 18 (17): 3548–3580. doi:10.1111/j.1365-294X.2009.04294.x. PMID 19674312. + +
      306. +
      307. + ^ Wright, Dawn; Bloomer, Sherman; MacLeod, Christopher; Taylor, Brian; Goodliffe, Andrew (2000). "Bathymetry of the Tonga Trench and Forearc: A Map Series". Marine Geophysical Researches. 21 (5): 489–512. Bibcode:2000MarGR..21..489W. doi:10.1023/A:1026514914220. + +
      308. +
      309. + ^ "Australasia". New Zealand Oxford Dictionary. Oxford University Press. 2005. doi:10.1093/acref/9780195584516.001.0001. ISBN 9780195584516. + +
      310. +
      311. + ^ Hobbs, Joseph J. (2016). Fundamentals of World Regional Geography. Cengage Learning. p. 367. ISBN 9781305854956. + +
      312. +
      313. + ^ Hillstrom, Kevin; Hillstrom, Laurie Collier (2003). Australia, Oceania, and Antarctica: A Continental Overview of Environmental Issues. 3. ABC-CLIO. p. 25. ISBN 9781576076941. …defined here as the continent nation of Australia, New Zealand, and twenty-two other island countries and territories sprinkled over more than 40 million square kilometres of the South Pacific. + +
      314. +
      315. + ^ a b Mullan, Brett; Tait, Andrew; Thompson, Craig (March 2009). "Climate – New Zealand's climate". Te Ara: The Encyclopedia of New Zealand. Retrieved 15 January 2011. + +
      316. +
      317. + ^ "Summary of New Zealand climate extremes". National Institute of Water and Atmospheric Research. 2004. Retrieved 30 April 2010. + +
      318. +
      319. + ^ Walrond, Carl (March 2009). "Natural environment – Climate". Te Ara: The Encyclopedia of New Zealand. Retrieved 15 January 2011. + +
      320. +
      321. + ^ "Mean monthly rainfall". National Institute of Water and Atmospheric Research. Archived from the original (XLS) on 3 May 2011. Retrieved 4 February 2011. + +
      322. +
      323. + ^ "Mean monthly sunshine hours". National Institute of Water and Atmospheric Research. Archived from the original (XLS) on 15 October 2008. Retrieved 4 February 2011. + +
      324. +
      325. + ^ "New Zealand climate and weather". Tourism New Zealand. Retrieved 13 November 2016. + +
      326. +
      327. + ^ "Climate data and activities". National Institute of Water and Atmospheric Research. Retrieved 11 February 2016. + +
      328. +
      329. + ^ Cooper, R.; Millener, P. (1993). "The New Zealand biota: Historical background and new research". Trends in Ecology & Evolution. 8 (12): 429. doi:10.1016/0169-5347(93)90004-9. + +
      330. +
      331. + ^ Trewick SA, Morgan-Richards M. 2014. New Zealand Wild Life. Penguin, New Zealand. + ISBN 9780143568896 +
      332. +
      333. + ^ Lindsey, Terence; Morris, Rod (2000). Collins Field Guide to New Zealand Wildlife. HarperCollins (New Zealand) Limited. p. 14. ISBN 978-1-86950-300-0. + +
      334. +
      335. + ^ a b "Frequently asked questions about New Zealand plants". New Zealand Plant Conservation Network. May 2010. Retrieved 15 January 2011. + +
      336. +
      337. + ^ De Lange, Peter James; Sawyer, John William David & Rolfe, Jeremy (2006). New Zealand indigenous vascular plant checklist. New Zealand Plant Conservation Network. ISBN 0-473-11306-6. + +
      338. +
      339. + ^ Wassilieff, Maggy (March 2009). "Lichens – Lichens in New Zealand". Te Ara: The Encyclopedia of New Zealand. Retrieved 16 January 2011. + +
      340. +
      341. + ^ McLintock, Alexander, ed. (April 2010) [originally published in 1966]. Mixed Broadleaf Podocarp and Kauri Forest. An Encyclopaedia of New Zealand. Retrieved 15 January 2011. + +
      342. +
      343. + ^ Mark, Alan (March 2009). "Grasslands – Tussock grasslands". Te Ara: The Encyclopedia of New Zealand. Retrieved 17 January 2010. + +
      344. +
      345. + ^ "Commentary on Forest Policy in the Asia-Pacific Region (A Review for Indonesia, Malaysia, New Zealand, Papua New Guinea, Philippines, Thailand and Western Samoa)". Forestry Department. 1997. Retrieved 4 February 2011. + +
      346. +
      347. + ^ McGlone, M.S. (1989). "The Polynesian settlement of New Zealand in relation to environmental and biotic changes" (PDF). New Zealand Journal of Ecology. 12(S): 115–129. Archived from the original (PDF) on 17 July 2014. + +
      348. +
      349. + ^ Taylor, R. and Smith, I. (1997). The state of New Zealand’s environment 1997. Ministry for the Environment, Wellington. +
      350. +
      351. + ^ "New Zealand ecology: Flightless birds". TerraNature. Retrieved 17 January 2011. + +
      352. +
      353. + ^ a b Holdaway, Richard (March 2009). "Extinctions – New Zealand extinctions since human arrival". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      354. +
      355. + ^ Kirby, Alex (January 2005). "Huge eagles 'dominated NZ skies'". BBC News. Retrieved 4 February 2011. + +
      356. +
      357. + ^ "Reptiles and frogs". Department of Conservation. Archived from the original on 29 January 2015. Retrieved 25 June 2017. + +
      358. +
      359. + ^ Pollard, Simon (September 2007). "Spiders and other arachnids". Te Ara: The Encyclopedia of New Zealand. Retrieved 25 June 2017. + +
      360. +
      361. + ^ "Wētā". Department of Conservation. Retrieved 25 June 2017. + +
      362. +
      363. + ^ Ryan, Paddy (March 2009). "Snails and slugs – Flax snails, giant snails and veined slugs". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      364. +
      365. + ^ Herrera-Flores, Jorge A.; Stubbs, Thomas L.; Benton, Michael J.; Ruta, Marcello (May 2017). "Macroevolutionary patterns in Rhynchocephalia: is the tuatara (Sphenodon punctatus) a living fossil?". Palaeontology. 60 (3): 319–328. doi:10.1111/pala.12284. + +
      366. +
      367. + ^ "Tiny Bones Rewrite Textbooks, first New Zealand land mammal fossil". University of New South Wales. 31 May 2007. Archived from the original on 31 May 2007. + +
      368. +
      369. + ^ Worthy, Trevor H.; Tennyson, Alan J. D.; Archer, Michael; Musser, Anne M.; Hand, Suzanne J.; Jones, Craig; Douglas, Barry J.; McNamara, James A.; Beck, Robin M. D. (2006). "Miocene mammal reveals a Mesozoic ghost lineage on insular New Zealand, southwest Pacific". Proceedings of the National Academy of Sciences of the United States of America. 103 (51): 19419–23. Bibcode:2006PNAS..10319419W. doi:10.1073/pnas.0605684103. PMC 1697831. PMID 17159151. + +
      370. +
      371. + ^ "Marine Mammals". Department of Conservation. Archived from the original on 8 March 2011. Retrieved 17 January 2011. + +
      372. +
      373. + ^ "Sea and shore birds". Department of Conservation. Retrieved 7 March 2011. + +
      374. +
      375. + ^ "Penguins". Department of Conservation. Retrieved 7 March 2011. + +
      376. +
      377. + ^ Jones, Carl (2002). "Reptiles and Amphibians". In Perrow, Martin; Davy, Anthony (eds.). Handbook of ecological restoration: Principles of Restoration. 2. Cambridge University Press. p. 362. ISBN 0-521-79128-6. + +
      378. +
      379. + ^ Towns, D.; Ballantine, W. (1993). "Conservation and restoration of New Zealand Island ecosystems". Trends in Ecology & Evolution. 8 (12): 452. doi:10.1016/0169-5347(93)90009-E. + +
      380. +
      381. + ^ Rauzon, Mark (2008). "Island restoration: Exploring the past, anticipating the future" (PDF). Marine Ornithology. 35: 97–107. + +
      382. +
      383. + ^ Diamond, Jared (1990). Towns, D; Daugherty, C; Atkinson, I (eds.). New Zealand as an archipelago: An international perspective (PDF). Wellington: Conservation Sciences Publication No. 2. Department of Conservation. pp. 3–8. + +
      384. +
      385. + ^ World Economic Outlook. International Monetary Fund. April 2018. p. 63. ISBN 978-1-48434-971-7. Retrieved 21 June 2018. + +
      386. +
      387. + ^ "Rankings on Economic Freedom". The Heritage Foundation. 2016. Retrieved 30 November 2016. + +
      388. +
      389. + ^ "Currencies of the territories listed in the BS exchange rate lists". Bank of Slovenia. Retrieved 22 January 2011. + +
      390. +
      391. + ^ a b c McLintock, Alexander, ed. (November 2009) [originally published in 1966]. Historical evolution and trade patterns. An Encyclopaedia of New Zealand. Retrieved 10 February 2011. + +
      392. +
      393. + ^ Stringleman, Hugh; Peden, Robert (October 2009). "Sheep farming – Growth of the frozen meat trade, 1882–2001". Te Ara: The Encyclopedia of New Zealand. Retrieved 6 May 2010. + +
      394. +
      395. + ^ Baker, John (February 2010) [1966]. McLintock, Alexander (ed.). Some Indicators of Comparative Living Standards. An Encyclopaedia of New Zealand. Retrieved 30 April 2010. + PDF Table +
      396. +
      397. + ^ Wilson, John (March 2009). "History – The later 20th century". Te Ara: The Encyclopedia of New Zealand. Retrieved 2 February 2011. + +
      398. +
      399. + ^ Nixon, Chris; Yeabsley, John (April 2010). "Overseas trade policy – Difficult times – the 1970s and early 1980s". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      400. +
      401. + ^ Evans, N. "Up From Down Under: After a Century of Socialism, Australia and New Zealand are Cutting Back Government and Freeing Their Economies". National Review. 46 (16): 47–51. + +
      402. +
      403. + ^ Trade, Food Security, and Human Rights: The Rules for International Trade in Agricultural Products and the Evolving World Food Crisis. Routledge. 2016. p. 125. ISBN 9781317008521. + +
      404. +
      405. + ^ Wayne Arnold (2 August 2007). "Surviving Without Subsidies". The New York Times. Retrieved 11 August 2015. ... ever since a liberal but free-market government swept to power in 1984 and essentially canceled handouts to farmers ... They went cold turkey and in the process it was very rough on their farming economy + +
      406. +
      407. + ^ Easton, Brian (November 2010). "Economic history – Government and market liberalisation". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 February 2011. + +
      408. +
      409. + ^ Hazledine, Tim (1998). Taking New Zealand Seriously: The Economics of Decency (PDF). HarperCollins Publishers. ISBN 1-86950-283-3. Archived from the original (PDF) on 10 May 2011. + +
      410. +
      411. + ^ "NZ tops Travellers' Choice Awards". Stuff Travel. May 2008. Retrieved 30 April 2010. + +
      412. +
      413. + ^ a b c "Unemployment: the Social Report 2016 – Te pūrongo oranga tangata". Ministry of Social Development. Retrieved 18 August 2017. + +
      414. +
      415. + ^ "New Zealand Takes a Pause in Cutting Rates". The New York Times. 10 June 2009. Retrieved 30 April 2010. + +
      416. +
      417. + ^ "New Zealand's slump longest ever". BBC News. 26 June 2009. Retrieved 30 April 2010. + +
      418. +
      419. + ^ Bascand, Geoff (February 2011). "Household Labour Force Survey: December 2010 quarter – Media Release". Statistics New Zealand. Archived from the original on 29 April 2011. Retrieved 4 February 2011. + +
      420. +
      421. + ^ Davenport, Sally (2004). "Panic and panacea: brain drain and science and technology human capital policy". Research Policy. 33 (4): 617–630. doi:10.1016/j.respol.2004.01.006. + +
      422. +
      423. + ^ O'Hare, Sean (September 2010). "New Zealand brain-drain worst in world". The Daily Telegraph. United Kingdom. + +
      424. +
      425. + ^ Collins, Simon (March 2005). "Quarter of NZ's brightest are gone". New Zealand Herald. + +
      426. +
      427. + ^ Winkelmann, Rainer (2000). "The labour market performance of European immigrants in New Zealand in the 1980s and 1990s". The International Migration Review. The Center for Migration Studies of New York. 33 (1): 33–58. doi:10.2307/2676011. JSTOR 2676011. + Journal subscription required +
      428. +
      429. + ^ Bain 2006, p. 44. +
      430. +
      431. + ^ "GII 2016 Report" (PDF). Global Innovation Index. Retrieved 21 June 2018. + +
      432. +
      433. + ^ Groser, Tim (March 2009). "Speech to ASEAN-Australia-New Zealand Free Trade Agreement Seminars". New Zealand Government. Retrieved 30 January 2011. + +
      434. +
      435. + ^ "Improving Access to Markets:Agriculture". New Zealand Ministry of Foreign Affairs and Trade. Retrieved 22 January 2011. + +
      436. +
      437. + ^ "Standard International Trade Classification R4 – Exports (Annual-Jun)". Statistics New Zealand. April 2015. Retrieved 3 April 2015. + +
      438. +
      439. + ^ a b c "Goods and services trade by country: Year ended June 2018 – corrected". Statistics New Zealand. Retrieved 17 February 2019. + +
      440. +
      441. + ^ "China and New Zealand sign free trade deal". The New York Times. April 2008. + +
      442. +
      443. + ^ a b "Key Tourism Statistics" (PDF). Ministry of Business, Innovation and Employment. 26 April 2017. Retrieved 26 April 2017. + +
      444. +
      445. + ^ Easton, Brian (March 2009). "Economy – Agricultural production". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      446. +
      447. + ^ Stringleman, Hugh; Peden, Robert (March 2009). "Sheep farming – Changes from the 20th century". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      448. +
      449. + ^ Stringleman, Hugh; Scrimgeour, Frank (November 2009). "Dairying and dairy products – Dairying in the 2000s". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      450. +
      451. + ^ Stringleman, Hugh; Scrimgeour, Frank (March 2009). "Dairying and dairy products – Dairy exports". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      452. +
      453. + ^ Stringleman, Hugh; Scrimgeour, Frank (March 2009). "Dairying and dairy products – Manufacturing and marketing in the 2000s". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      454. +
      455. + ^ Dalley, Bronwyn (March 2009). "Wine – The wine boom, 1980s and beyond". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      456. +
      457. + ^ "Wine in New Zealand". The Economist. 27 March 2008. Retrieved 29 April 2017. + +
      458. +
      459. + ^ "Agricultural and forestry exports from New Zealand: Primary sector export values for the year ending June 2010". Ministry of Agriculture and Forestry. 14 January 2011. Archived from the original on 10 May 2011. Retrieved 8 April 2011. + +
      460. +
      461. + ^ a b Energy in New Zealand 2016 (PDF) (Report). Ministry of Business, Innovation and Employment. September 2016. p. 47. ISSN 2324-5913. Archived from the original (PDF) on 3 May 2017. + +
      462. +
      463. + ^ "Appendix 1: Technical information about drinking water supply in the eight local authorities". Office of the Auditor-General. Retrieved 2 September 2016. + +
      464. +
      465. + ^ "Water supply". Greater Wellington Regional Council. Retrieved 2 September 2016. + +
      466. +
      467. + ^ "State highway frequently asked questions". NZ Transport Agency. Retrieved 28 April 2017. + +
      468. +
      469. + ^ Humphris, Adrian (April 2010). "Public transport – Passenger trends". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      470. +
      471. + ^ Atkinson, Neill (November 2010). "Railways – Rail transformed". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      472. +
      473. + ^ "About Metlink". Retrieved 27 December 2016. + +
      474. +
      475. + ^ Atkinson, Neill (April 2010). "Railways – Freight transport". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      476. +
      477. + ^ "International Visitors" (PDF). Ministry of Economic Development. June 2009. Retrieved 30 January 2011. + +
      478. +
      479. + ^ "10. Airports". Infrastructure Stocktake: Infrastructure Audit. Ministry of Economic Development. December 2005. Archived from the original on 22 May 2010. Retrieved 30 January 2011. + +
      480. +
      481. + ^ a b Wilson, A. C. (March 2010). "Telecommunications - Telecom". Te Ara: The Encyclopedia of New Zealand. Retrieved 11 August 2017. + +
      482. +
      483. + ^ "Telecom separation". Ministry of Business, Innovation and Employment. 14 September 2015. Retrieved 11 August 2017. + +
      484. +
      485. + ^ "Broadband and mobile programmes - Ministry of Business, Innovation & Employment". www.mbie.govt.nz. + +
      486. +
      487. + ^ "2017 Global ICT Development Index". International Telecommunication Union (ITU). 2018. Retrieved 18 September 2018. + +
      488. +
      489. + ^ "2013 Census usually resident population counts". Statistics New Zealand. 14 October 2013. Retrieved 20 September 2018. + +
      490. +
      491. + ^ "National population projections: 2016(base)–2068" (Press release). Statistics New Zealand. 18 October 2016. Retrieved 20 October 2018. + +
      492. +
      493. + ^ "Subnational population estimates at 30 June 2009". Statistics New Zealand. 30 June 2007. Retrieved 30 April 2010. + +
      494. +
      495. + ^ "Quality of Living Ranking 2016". London: Mercer. 23 February 2016. Retrieved 28 April 2017. + +
      496. +
      497. + ^ "NZ life expectancy among world's best". Stuff.co.nz. Fairfax NZ. Retrieved 6 July 2014. + +
      498. +
      499. + ^ a b Department of Economic and Social Affairs Population Division (2009). "World Population Prospects" (PDF). 2008 revision. United Nations. Retrieved 29 August 2009. + +
      500. +
      501. + ^ "World Factbook EUROPE : NEW ZEALAND", The World Factbook, 12 July 2018 + +
      502. +
      503. + ^ "New Zealand mortality statistics: 1950 to 2010" (PDF). Ministry of Health of New Zealand. 2 March 2011. Retrieved 16 November 2016. + +
      504. +
      505. + ^ "Health expenditure and financing". stats.oecd.org. OECD. 2016. Retrieved 8 December 2017. + +
      506. +
      507. + ^ "Subnational Population Estimates: At 30 June 2018 (provisional)". Statistics New Zealand. 23 October 2018. Retrieved 23 October 2018. + For urban areas, "Subnational population estimates (UA, AU), by age and sex, at 30 June 1996, 2001, 2006-18 (2017 boundaries)". Statistics New Zealand. 23 October 2018. Retrieved 23 October 2018. + +
      508. +
      509. + ^ "2013 Census QuickStats about culture and identity – Ethnic groups in New Zealand". Statistics New Zealand. Retrieved 29 August 2014. + +
      510. +
      511. + ^ Pool, Ian (May 2011). "Population change - Key population trends". Te Ara: The Encyclopedia of New Zealand. Archived from the original on 18 August 2017. Retrieved 18 August 2017. + +
      512. +
      513. + ^ Dalby, Simon (September 1993). "The 'Kiwi disease': geopolitical discourse in Aotearoa/New Zealand and the South Pacific". Political Geography. 12 (5): 437–456. doi:10.1016/0962-6298(93)90012-V. + +
      514. +
      515. + ^ Callister, Paul (2004). "Seeking an Ethnic Identity: Is "New Zealander" a Valid Ethnic Category?" (PDF). New Zealand Population Review. 30 (1&2): 5–22. + +
      516. +
      517. + ^ Bain 2006, p. 31. +
      518. +
      519. + ^ "Draft Report of a Review of the Official Ethnicity Statistical Standard: Proposals to Address the 'New Zealander' Response Issue" (PDF). Statistics New Zealand. April 2009. Retrieved 18 January 2011. + +
      520. +
      521. + ^ Ranford, Jodie. "'Pakeha', Its Origin and Meaning". Māori News. Retrieved 20 February 2008. Originally the Pakeha were the early European settlers, however, today ‘Pakeha’ is used to describe any peoples of non-Maori or non-Polynesian heritage. Pakeha is not an ethnicity but rather a way to differentiate between the historical origins of our settlers, the Polynesians and the Europeans, the Maori and the other + +
      522. +
      523. + ^ Socidad Peruana de Medicina Intensiva (SOPEMI) (2000). Trends in international migration: continuous reporting system on migration. Organisation for Economic Co-operation and Development. pp. 276–278. + +
      524. +
      525. + ^ Walrond, Carl (21 September 2007). "Dalmatians". Te Ara: The Encyclopedia of New Zealand. Retrieved 30 April 2010. + +
      526. +
      527. + ^ "Peoples". Te Ara: The Encyclopedia of New Zealand. 2005. Retrieved 2 June 2017. + +
      528. +
      529. + ^ a b Phillips, Jock (11 August 2015). "History of immigration". Te Ara: The Encyclopedia of New Zealand. Retrieved 2 June 2017. + +
      530. +
      531. + ^ Brawley, Sean (1993). "'No White Policy in NZ': Fact and Fiction in New Zealand's Asian Immigration Record, 1946-1978" (PDF). New Zealand Journal of History. 27 (1): 33–36. Retrieved 2 June 2017. + +
      532. +
      533. + ^ "International Migration Outlook – New Zealand 2009/10" (PDF). New Zealand Department of Labour. 2010. p. 2. ISSN 1179-5085. Archived from the original (PDF) on 11 May 2011. Retrieved 16 April 2011. + +
      534. +
      535. + ^ "2013 Census QuickStats about culture and identity – Birthplace and people born overseas". Statistics New Zealand. Retrieved 29 August 2014. + +
      536. +
      537. + ^ Butcher, Andrew; McGrath, Terry (2004). "International Students in New Zealand: Needs and Responses" (PDF). International Education Journal. 5 (4). + +
      538. +
      539. + ^ 2013 Census QuickStats, Statistics New Zealand, 2013, ISBN 978-0-478-40864-5 + +
      540. +
      541. + ^ a b c "2013 Census QuickStats about culture and identity – Languages spoken". Statistics New Zealand. Retrieved 8 September 2016. + +
      542. +
      543. + ^ Hay, Maclagan & Gordon 2008, p. 14. +
      544. +
      545. + ^ * Bauer, Laurie; Warren, Paul; Bardsley, Dianne; Kennedy, Marianna; Major, George (2007), "New Zealand English", Journal of the International Phonetic Association, 37 (1): 97–102, doi:10.1017/S0025100306002830 + +
      546. +
      547. + ^ a b Phillips, Jock (March 2009). "The New Zealanders – Bicultural New Zealand". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      548. +
      549. + ^ Squires, Nick (May 2005). "British influence ebbs as New Zealand takes to talking Māori". The Daily Telegraph. Retrieved 3 May 2017. + +
      550. +
      551. + ^ "Waitangi Tribunal claim – Māori Language Week". Ministry for Culture and Heritage. July 2010. Retrieved 19 January 2011. + +
      552. +
      553. + ^ "Ngā puna kōrero: Where Māori speak te reo – infographic". Statistics New Zealand. Retrieved 8 September 2016. + +
      554. +
      555. + ^ Drinnan, John (8 July 2016). "'Maori' will remain in the name Maori Television". New Zealand Herald. Retrieved 28 August 2016. According to 2015 figures supplied by Maori TV, its two channels broadcast an average of 72 per cent Maori language content - 59 per cent on the main channel and 99 per cent on te reo. + +
      556. +
      557. + ^ "Ngāi Tahu Claims Settlement Act 1998". New Zealand Parliamentary Counsel Office. 20 May 2014 [1 October 1998]. Retrieved 10 March 2019. + +
      558. +
      559. + ^ New Zealand Sign Language Act 2006 No 18 (as at 30 June 2008), Public Act. New Zealand Parliamentary Counsel Office. Retrieved 29 November 2011. +
      560. +
      561. + ^ Zuckerman, Phil (2006). Martin, Michael (ed.). The Cambridge Companion to Atheism (PDF). Cambridge University Press. pp. 47–66. ISBN 978-0-521-84270-9. Retrieved 8 August 2017. + +
      562. +
      563. + ^ Walrond, Carl (May 2012). "Atheism and secularism – Who is secular?". Te Ara: The Encyclopedia of New Zealand. Retrieved 8 August 2017. + +
      564. + +
      565. + ^ a b c "2013 Census QuickStats about culture and identity – tables". Statistics New Zealand. 15 April 2014. Retrieved 14 April 2018. + Excel download +
      566. +
      567. + ^ Kaa, Hirini (May 2011). "Māori and Christian denominations". Te Ara: The Encyclopedia of New Zealand. Retrieved 20 April 2017. + +
      568. +
      569. + ^ Morris, Paul (May 2011). "Diverse religions". Te Ara: The Encyclopedia of New Zealand. Retrieved 20 April 2017. + +
      570. +
      571. + ^ a b Dench, Olivia (July 2010). "Education Statistics of New Zealand: 2009". Education Counts. Retrieved 19 January 2011. + +
      572. +
      573. + ^ "Education Act 1989 No 80". New Zealand Parliamentary Counsel Office. 1989. Section 3. Retrieved 5 January 2013. + +
      574. +
      575. + ^ "Education Act 1989 No 80 (as at 01 February 2011), Public Act. Part 14: Establishment and disestablishment of tertiary institutions, Section 62: Establishment of institutions". Education Act 1989 No 80. New Zealand Parliamentary Counsel Office. 1 February 2011. Retrieved 15 August 2011. + +
      576. +
      577. + ^ "Studying in New Zealand: Tertiary education". New Zealand Qualifications Authority. Retrieved 15 August 2011. + +
      578. +
      579. + ^ "Educational attainment of the population". Education Counts. 2006. Archived from the original (xls) on 15 October 2008. Retrieved 21 February 2008. + +
      580. +
      581. + ^ "What Students Know and Can Do: Student Performance in Reading, Mathematics and Science 2010" (PDF). + OECD. Retrieved 21 July 2012. +
      582. +
      583. + ^ Kennedy 2007, p. 398. +
      584. +
      585. + ^ Hearn, Terry (March 2009). "English – Importance and influence". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      586. +
      587. + ^ "Conclusions – British and Irish immigration". Ministry for Culture and Heritage. March 2007. Retrieved 21 January 2011. + +
      588. +
      589. + ^ Stenhouse, John (November 2010). "Religion and society – Māori religion". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      590. +
      591. + ^ "Māori Social Structures". Ministry of Justice. March 2001. Retrieved 21 January 2011. + +
      592. +
      593. + ^ "Thousands turn out for Pasifika Festival". Radio New Zealand. 25 March 2017. Retrieved 18 August 2017. + +
      594. +
      595. + ^ Kennedy 2007, p. 400. +
      596. +
      597. + ^ Kennedy 2007, p. 399. +
      598. +
      599. + ^ Phillips, Jock (March 2009). "The New Zealanders – Post-war New Zealanders". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      600. +
      601. + ^ Phillips, Jock (March 2009). "The New Zealanders – Ordinary blokes and extraordinary sheilas". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      602. +
      603. + ^ Phillips, Jock (March 2009). "Rural mythologies – The cult of the pioneer". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      604. +
      605. + ^ Barker, Fiona (June 2012). "New Zealand identity – Culture and arts". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 December 2016. + +
      606. +
      607. + ^ a b Wilson, John (September 2016). "Nation and government – Nationhood and identity". Te Ara: The Encyclopedia of New Zealand. Retrieved 3 December 2016. + +
      608. +
      609. + ^ a b Swarbrick, Nancy (June 2010). "Creative life – Visual arts and crafts". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      610. +
      611. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Elements of Carving. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      612. +
      613. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Surface Patterns. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      614. +
      615. + ^ McKay, Bill (2004). "Māori architecture: transforming western notions of architecture". Fabrications. 14 (1&2): 1–12. doi:10.1080/10331867.2004.10525189. Archived from the original on 13 May 2011. + +
      616. +
      617. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Painted Designs. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      618. +
      619. + ^ McLintock, Alexander, ed. (2009) [1966]. Tattooing. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      620. +
      621. + ^ a b "Beginnings – history of NZ painting". Ministry for Culture and Heritage. December 2010. Retrieved 17 February 2011. + +
      622. +
      623. + ^ "A new New Zealand art – history of NZ painting". Ministry for Culture and Heritage. November 2010. Retrieved 16 February 2011. + +
      624. +
      625. + ^ "Contemporary Maori art". Ministry for Culture and Heritage. November 2010. Retrieved 16 February 2011. + +
      626. +
      627. + ^ Rauer, Julie. "Paradise Lost: Contemporary Pacific Art At The Asia Society". Asia Society and Museum. Retrieved 17 February 2011. + +
      628. +
      629. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Textile Designs. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      630. +
      631. + ^ Keane, Basil (March 2009). "Pounamu – jade or greenstone – Implements and adornment". Te Ara: The Encyclopedia of New Zealand. Retrieved 17 February 2011. + +
      632. +
      633. + ^ Wilson, John (March 2009). "Society – Food, drink and dress". Te Ara: The Encyclopedia of New Zealand. Retrieved 17 February 2011. + +
      634. +
      635. + ^ Swarbrick, Nancy (June 2010). "Creative life – Design and fashion". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      636. +
      637. + ^ a b "Fashion in New Zealand – New Zealand's fashion industry". The Economist. 28 February 2008. Retrieved 6 August 2009. + +
      638. +
      639. + ^ Swarbrick, Nancy (June 2010). "Creative life – Writing and publishing". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      640. +
      641. + ^ "The making of New Zealand literature". Ministry for Culture and Heritage. November 2010. Retrieved 22 January 2011. + +
      642. +
      643. + ^ "New directions in the 1930s – New Zealand literature". Ministry for Culture and Heritage. August 2008. Retrieved 12 February 2011. + +
      644. +
      645. + ^ "The war and beyond – New Zealand literature". Ministry for Culture and Heritage. November 2007. Retrieved 12 February 2011. + +
      646. +
      647. + ^ "28 cities join the UNESCO Creative Cities Network". UNESCO. December 2014. Retrieved 7 March 2015. + +
      648. +
      649. + ^ a b Swarbrick, Nancy (June 2010). "Creative life – Music". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      650. +
      651. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Maori Music. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      652. +
      653. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Musical Instruments. An Encyclopaedia of New Zealand. Retrieved 16 February 2011. + +
      654. +
      655. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Instruments Used for Non-musical Purposes. An Encyclopaedia of New Zealand. Retrieved 16 February 2011. + +
      656. +
      657. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Music: General History. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      658. +
      659. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Music: Brass Bands. An Encyclopaedia of New Zealand. Retrieved 14 April 2011. + +
      660. +
      661. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Music: Pipe Bands. An Encyclopaedia of New Zealand. Retrieved 14 April 2011. + +
      662. +
      663. + ^ Swarbrick, Nancy (June 2010). "Creative life – Performing arts". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      664. +
      665. + ^ "History – celebrating our music since 1965". Recording Industry Association of New Zealand. 2008. Archived from the original on 14 September 2011. Retrieved 23 January 2012. + +
      666. +
      667. + ^ "About RIANZ – Introduction". Recording Industry Association of New Zealand. Archived from the original on 21 December 2011. Retrieved 23 January 2012. + +
      668. +
      669. + ^ Downes, Siobhan (1 January 2017). "World famous in New Zealand: Hobbiton Movie Set". Stuff Travel. Retrieved 6 July 2017. + +
      670. +
      671. + ^ Brian, Pauling (October 2014). "Radio – The early years, 1921 to 1932". Te Ara: The Encyclopedia of New Zealand. Retrieved 6 July 2017. + +
      672. +
      673. + ^ "New Zealand's first official TV broadcast". Ministry for Culture and Heritage. December 2016. Retrieved 6 July 2017. + +
      674. +
      675. + ^ a b Swarbrick, Nancy (June 2010). "Creative life – Film and broadcasting". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      676. +
      677. + ^ Horrocks, Roger. "A History of Television in New Zealand". NZ On Screen. Retrieved 13 September 2017. + +
      678. +
      679. + ^ "Top 10 Highest Grossing New Zealand Movies Ever". Flicks.co.nz. May 2016. Retrieved 11 August 2017. + +
      680. +
      681. + ^ Cieply, Michael; Rose, Jeremy (October 2010). "New Zealand Bends and 'Hobbit' Stays". The New York Times. Retrieved 11 August 2017. + +
      682. +
      683. + ^ "Production Guide: Locations". Film New Zealand. Archived from the original on 7 November 2010. Retrieved 21 January 2011. + +
      684. +
      685. + ^ Myllylahti, Merja (December 2016). JMAD New Zealand Media Ownership Report 2016 (PDF) (Report). Auckland University of Technology. pp. 4–29. Archived from the original (PDF) on 21 May 2017. Retrieved 11 August 2017. + +
      686. +
      687. + ^ "Scores and Status Data 1980-2015". Freedom of the Press 2015. Freedom House. Retrieved 23 November 2016. + +
      688. +
      689. + ^ Hearn, Terry (March 2009). "English – Popular culture". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2012. + +
      690. +
      691. + ^ "Sport, Fitness and Leisure". New Zealand Official Yearbook. Statistics New Zealand. 2000. Archived from the original on 7 June 2011. Retrieved 21 July 2008. Traditionally New Zealanders have excelled in rugby union, which is regarded as the national sport, and track and field athletics. + +
      692. +
      693. + ^ a b Phillips, Jock (February 2011). "Sports and leisure – Organised sports". Te Ara: The Encyclopedia of New Zealand. Retrieved 23 March 2011. + +
      694. +
      695. + ^ a b "More and more students wear school sports colours". New Zealand Secondary School Sports Council. Retrieved 30 March 2015. + +
      696. +
      697. + ^ Crawford, Scott (January 1999). "Rugby and the Forging of National Identity". In Nauright, John (ed.). Sport, Power And Society In New Zealand: Historical And Contemporary Perspectives (PDF). ASSH Studies In Sports History. Archived from the original (PDF) on 19 January 2012. Retrieved 22 January 2011. + +
      698. +
      699. + ^ "Rugby, racing and beer". Ministry for Culture and Heritage. August 2010. Retrieved 22 January 2011. + +
      700. +
      701. + ^ Derby, Mark (December 2010). "Māori–Pākehā relations – Sports and race". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      702. +
      703. + ^ Bain 2006, p. 69. +
      704. +
      705. + ^ Langton, Graham (1996). A history of mountain climbing in New Zealand to 1953 (Thesis). Christchurch: University of Canterbury. p. 28. Retrieved 12 August 2017. + +
      706. +
      707. + ^ "World mourns Sir Edmund Hillary". The Age. Melbourne. 11 January 2008. + +
      708. +
      709. + ^ "Sport and Recreation Participation Levels" (PDF). Sport and Recreation New Zealand. 2009. Archived from the original (PDF) on 15 January 2015. Retrieved 27 November 2016. + +
      710. +
      711. + ^ Barclay-Kerr, Hoturoa (September 2013). "Waka ama – outrigger canoeing". Te Ara: The Encyclopedia of New Zealand. Retrieved 12 August 2017. + +
      712. +
      713. + ^ "NZ's first Olympic century". Ministry for Culture and Heritage. August 2016. Retrieved 27 April 2017. + +
      714. +
      715. + ^ "London 2012 Olympic Games: Medal strike rate – Final count (revised)". Statistics New Zealand. 14 August 2012. Retrieved 4 December 2013. + +
      716. +
      717. + ^ "Rio 2016 Olympic Games: Medals per capita". Statistics New Zealand. 30 August 2016. Retrieved 27 April 2017. + +
      718. +
      719. + ^ Kerr, James (14 November 2013). "The All Blacks guide to being successful (off the field)". The Daily Telegraph. London. Retrieved 4 December 2013. + +
      720. +
      721. + ^ Fordyce, Tom (23 October 2011). "2011 Rugby World Cup final: New Zealand 8-7 France". BBC Sport. Retrieved 4 December 2013. + +
      722. +
      723. + ^ a b "New Zealand Cuisine". New Zealand Tourism Guide. January 2016. Retrieved 4 January 2016. + +
      724. +
      725. + ^ Petrie, Hazel (November 2008). "Kai Pākehā – introduced foods". Te Ara: The Encyclopedia of New Zealand. Retrieved 27 June 2017. + +
      726. +
      727. + ^ Whaanga, Mere (June 2006). "Mātaitai – shellfish gathering". Te Ara: The Encyclopedia of New Zealand. Retrieved 27 June 2017. + +
      728. +
      729. + ^ "Story: Shellfish". Te Ara: The Encyclopedia of New Zealand. Retrieved 29 August 2016. + +
      730. +
      731. + ^ Burton, David (September 2013). "Cooking – Cooking methods". Te Ara: The Encyclopedia of New Zealand. Retrieved 11 December 2016. + +
      732. +
      733. + ^ Royal, Charles; Kaka-Scott, Jenny (September 2013). "Māori foods – kai Māori". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 September 2016. + +
      734. +
      +
      +

      + References +

      +
      +
        +
      • + Alley, Roderic (2008). New Zealand in World Affairs IV 1990–2005. New Zealand: Victoria University Press. ISBN 978-0-864-73548-5. + +
      • +
      • + Bain, Carolyn (2006). New Zealand. Lonely Planet. ISBN 1-74104-535-5. + +
      • +
      • + Garden, Donald (2005). Stoll, Mark (ed.). Australia, New Zealand, and the Pacific: An Environmental History. Nature and Human Societies. ABC-CLIO/Greenwood. ISBN 978-1-57607-868-6. + +
      • +
      • + Hay, Jennifer; Maclagan, Margaret; Gordon, Elizabeth (2008). Dialects of English: New Zealand English. Edinburgh University Press. ISBN 978-0-7486-2529-1. + +
      • +
      • + Kennedy, Jeffrey (2007). "Leadership and Culture in New Zealand". In Chhokar, Jagdeep; Brodbeck, Felix; House, Robert (eds.). Culture and Leadership Across the World: The GLOBE Book of In-Depth Studies of 25 Societies. United States: Psychology Press. ISBN 978-0-8058-5997-3. + +
      • +
      • + King, Michael (2003). The Penguin History of New Zealand. New Zealand: Penguin Books. ISBN 978-0-14-301867-4. + +
      • +
      • + Mein Smith, Philippa (2005). A Concise History of New Zealand. Australia: Cambridge University Press. ISBN 0-521-54228-6. + +
      • +
      • + Smelt, Roselynn; Jui Lin, Yong (2009). New Zealand. Cultures of the World (2nd ed.). New York: Marshall Cavendish. ISBN 978-0-7614-3415-3. + +
      • +
      +
      +

      + Further reading +

      + + +

      + External links +

      + +
      +
      + Government +
      +
      + +
      +
      + Travel +
      +
      + +
      +
      + General Information +
      +
      + + + + + + +
      \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/source.html new file mode 100644 index 000000000..09839304a --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-2/source.html @@ -0,0 +1,7228 @@ + + + + + + New Zealand - Wikipedia + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      + +
      + +
      +
      +
      + This is a good article. Follow the link for more information. +
      +
      + Page semi-protected +
      +
      +

      + New Zealand +

      +
      +
      + From Wikipedia, the free encyclopedia +
      +
      +
      Jump to navigation Jump to search +
      +
      + + +

      + +

      + Coordinates: 42°S 174°E / 42°S 174°E / -42; 174 +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + New Zealand +

      +
      + Aotearoa  (Māori) +
      +
      +
      +
      +
      + Blue field with the Union Flag in the top right corner, and four red stars with white borders to the right. +
      +
      + Flag +
      +
      +
      +
      + A quartered shield, flanked by two figures, topped with a crown. +
      + +
      +
      +
      +
      + Anthems:
      +
      + +
      +
      +
      + A map of the hemisphere centred on New Zealand, using an orthographic projection. +
      + Location of New Zealand, including outlying islands, its territorial claim in the Antarctic, and Tokelau +
      +
      + Capital + + Wellington
      + 41°17′S 174°27′E / 41.283°S 174.450°E / -41.283; 174.450 +
      + Largest city + + Auckland +
      + Official languages + +
      + +
      +
      + Ethnic groups +
      + (2018) +
      +
      +
      + +
      +
      + Demonym(s) + + New Zealander
      + Kiwi (informal) +
      + Government + + Unitary parliamentary constitutional monarchy +
      +
      + • Monarch +
      +
      + Elizabeth II +
      +
      + • Governor-General +
      +
      + Patsy Reddy +
      +
      + • Prime Minister +
      +
      + Jacinda Ardern +
      + Legislature + + Parliament
      + (House of Representatives) +
      + Stages of independence  +
      + from the United Kingdom +
      +
      + + + 7 May 1856 +
      +
      + • Dominion +
      +
      + 26 September 1907 +
      + + +
      + 25 November 1947 +
      + Area +
      +
      + • Total +
      +
      + 268,021 km2 (103,483 sq mi) (75th) +
      +
      + • Water (%) +
      +
      + 1.6[n 4] +
      + Population +
      +
      + • September 2019 estimate +
      +
      + 4,933,210[5] (120th) +
      +
      + • 2018 census +
      +
      + 4,699,755 +
      +
      + • Density +
      +
      + 18.2/km2 (47.1/sq mi) (203rd) +
      + GDP (PPP) + + 2018 estimate +
      +
      + • Total +
      +
      + $199 billion[6] +
      +
      + • Per capita +
      +
      + $40,266[6] +
      + GDP (nominal) + + 2018 estimate +
      +
      + • Total +
      +
      + $206 billion[6] +
      +
      + • Per capita +
      +
      + $41,616[6] +
      + Gini (2014) + + 33.0[7]
      + medium · 22nd +
      + HDI (2017) + + Increase 0.917[8]
      + very high · 16th +
      + Currency + + New Zealand dollar ($) (NZD) +
      + Time zone + + UTC+12 (NZST[n 5]) +
      +
      + • Summer (DST) +
      +
      + UTC+13 (NZDT[n 6]) +
      + Date format + + dd/mm/yyyy
      + yyyy-mm-dd[10] +
      + Driving side + + left +
      + Calling code + + +64 +
      + ISO 3166 code + + NZ +
      + Internet TLD + + .nz +
      +

      + New Zealand (Māori: Aotearoa [aɔˈtɛaɾɔa]) is a sovereign island country in the southwestern Pacific Ocean. The country geographically comprises two main landmasses—the North Island (Te Ika-a-Māui), and the South Island (Te Waipounamu)—and around 600 smaller islands. It has a total land area of 268,000 square kilometres (103,500 sq mi). New Zealand is situated some 2,000 kilometres (1,200 mi) east of Australia across the Tasman Sea and roughly 1,000 kilometres (600 mi) south of the Pacific island areas of New Caledonia, Fiji, and Tonga. Because of its remoteness, it was one of the last lands to be settled by humans. During its long period of isolation, New Zealand developed a distinct biodiversity of animal, fungal, and plant life. The country's varied topography and its sharp mountain peaks, such as the Southern Alps, owe much to the tectonic uplift of land and volcanic eruptions. New Zealand's capital city is Wellington, while its most populous city is Auckland. +

      +

      + Sometime between 1250 and 1300, Polynesians settled in the islands that later were named New Zealand and developed a distinctive Māori culture. In 1642, Dutch explorer Abel Tasman became the first European to sight New Zealand. In 1840, representatives of the United Kingdom and Māori chiefs signed the Treaty of Waitangi, which declared British sovereignty over the islands. In 1841, New Zealand became a colony within the British Empire and in 1907 it became a dominion; it gained full statutory independence in 1947 and the British monarch remained the head of state. Today, the majority of New Zealand's population of 4.9 million is of European descent; the indigenous Māori are the largest minority, followed by Asians and Pacific Islanders. Reflecting this, New Zealand's culture is mainly derived from Māori and early British settlers, with recent broadening arising from increased immigration. The official languages are English, Māori, and New Zealand Sign Language, with English being very dominant. +

      +

      + A developed country, New Zealand ranks highly in international comparisons of national performance, such as quality of life, health, education, protection of civil liberties, and economic freedom. New Zealand underwent major economic changes during the 1980s, which transformed it from a protectionist to a liberalised free-trade economy. The service sector dominates the national economy, followed by the industrial sector, and agriculture; international tourism is a significant source of revenue. Nationally, legislative authority is vested in an elected, unicameral Parliament, while executive political power is exercised by the Cabinet, led by the prime minister, currently Jacinda Ardern. Queen Elizabeth II is the country's monarch and is represented by a governor-general, currently Dame Patsy Reddy. In addition, New Zealand is organised into 11 regional councils and 67 territorial authorities for local government purposes. The Realm of New Zealand also includes Tokelau (a dependent territory); the Cook Islands and Niue (self-governing states in free association with New Zealand); and the Ross Dependency, which is New Zealand's territorial claim in Antarctica. New Zealand is a member of the United Nations, Commonwealth of Nations, ANZUS, Organisation for Economic Co-operation and Development, ASEAN Plus Six, Asia-Pacific Economic Cooperation, the Pacific Community and the Pacific Islands Forum. +

      + +

      + Etymology +

      + +
      +
      + Brown square paper with Dutch writing and a thick red, curved line +
      +
      + +
      Detail from a 1657 map showing the western coastline of "Nova Zeelandia". (In this map, north is at the bottom.) +
      +
      +
      +

      + Dutch explorer Abel Tasman sighted New Zealand in 1642 and named it Staten Land "in honour of the States General" (Dutch parliament). He wrote, "it is possible that this land joins to the Staten Land but it is uncertain",[11] referring to a landmass of the same name at the southern tip of South America, discovered by Jacob Le Maire in 1616.[12][13] In 1645, Dutch cartographers renamed the land Nova Zeelandia after the Dutch province of Zeeland.[14][15] British explorer James Cook subsequently anglicised the name to New Zealand.[16] +

      +

      + Aotearoa (pronounced /ˌtɛəˈr.ə/; often translated as "land of the long white cloud")[17] is the current Māori name for New Zealand. It is unknown whether Māori had a name for the whole country before the arrival of Europeans, with Aotearoa originally referring to just the North Island.[18] Māori had several traditional names for the two main islands, including Te Ika-a-Māui (the fish of Māui) for the North Island and Te Waipounamu (the waters of greenstone) or Te Waka o Aoraki (the canoe of Aoraki) for the South Island.[19] Early European maps labelled the islands North (North Island), Middle (South Island) and South (Stewart Island / Rakiura).[20] In 1830, mapmakers began to use "North" and "South" on their maps to distinguish the two largest islands and by 1907 this was the accepted norm.[16] The New Zealand Geographic Board discovered in 2009 that the names of the North Island and South Island had never been formalised, and names and alternative names were formalised in 2013. This set the names as North Island or Te Ika-a-Māui, and South Island or Te Waipounamu.[21] For each island, either its English or Māori name can be used, or both can be used together.[21] +

      +
      +

      + History +

      + +
      +
      + One set of arrows point from Taiwan to Melanesia to Fiji/Samoa and then to the Marquesas Islands. The population then spread, some going south to New Zealand and others going north to Hawai'i. A second set start in southern Asia and end in Melanesia. +
      +
      + +
      The Māori people are most likely descended from people who emigrated from Taiwan to Melanesia and then travelled east through to the Society Islands. After a pause of 70 to 265 years, a new wave of exploration led to the discovery and settlement of New Zealand.[22] +
      +
      +
      +

      + New Zealand was one of the last major landmasses settled by humans. Radiocarbon dating, evidence of deforestation[23] and mitochondrial DNA variability within Māori populations[24] suggest New Zealand was first settled by Eastern Polynesians between 1250 and 1300,[19][25] concluding a long series of voyages through the southern Pacific islands.[26] Over the centuries that followed, these settlers developed a distinct culture now known as Māori. The population was divided into iwi (tribes) and hapū (subtribes) who would sometimes cooperate, sometimes compete and sometimes fight against each other.[27] At some point a group of Māori migrated to Rēkohu, now known as the Chatham Islands, where they developed their distinct Moriori culture.[28][29] The Moriori population was all but wiped out between 1835 and 1862, largely because of Taranaki Māori invasion and enslavement in the 1830s, although European diseases also contributed. In 1862 only 101 survived, and the last known full-blooded Moriori died in 1933.[30] +

      +
      +
      + An engraving of a sketched coastline on white background +
      +
      + +
      Map of the New Zealand coastline as Cook charted it on his first visit in 1769–70. The track of the Endeavour is also shown. +
      +
      +
      +

      + The first Europeans known to have reached New Zealand were Dutch explorer Abel Tasman and his crew in 1642.[31] In a hostile encounter, four crew members were killed and at least one Māori was hit by canister shot.[32] Europeans did not revisit New Zealand until 1769 when British explorer James Cook mapped almost the entire coastline.[31] Following Cook, New Zealand was visited by numerous European and North American whaling, sealing and trading ships. They traded European food, metal tools, weapons and other goods for timber, Māori food, artefacts and water.[33] The introduction of the potato and the musket transformed Māori agriculture and warfare. Potatoes provided a reliable food surplus, which enabled longer and more sustained military campaigns.[34] The resulting intertribal Musket Wars encompassed over 600 battles between 1801 and 1840, killing 30,000–40,000 Māori.[35] From the early 19th century, Christian missionaries began to settle New Zealand, eventually converting most of the Māori population.[36] The Māori population declined to around 40% of its pre-contact level during the 19th century; introduced diseases were the major factor.[37] +

      +
      +
      + A torn sheet of paper +
      +
      + +
      The Waitangi sheet from the Treaty of Waitangi +
      +
      +
      +

      + In 1788 Captain Arthur Phillip assumed the position of Governor of the new British colony of New South Wales which according to his commission included New Zealand.[38] The British Government appointed James Busby as British Resident to New Zealand in 1832 following a petition from northern Māori.[39] In 1835, following an announcement of impending French settlement by Charles de Thierry, the nebulous United Tribes of New Zealand sent a Declaration of Independence to King William IV of the United Kingdom asking for protection.[39] Ongoing unrest, the proposed settlement of New Zealand by the New Zealand Company (which had already sent its first ship of surveyors to buy land from Māori) and the dubious legal standing of the Declaration of Independence prompted the Colonial Office to send Captain William Hobson to claim sovereignty for the United Kingdom and negotiate a treaty with the Māori.[40] The Treaty of Waitangi was first signed in the Bay of Islands on 6 February 1840.[41] In response to the New Zealand Company's attempts to establish an independent settlement in Wellington[42] and French settlers purchasing land in Akaroa,[43] Hobson declared British sovereignty over all of New Zealand on 21 May 1840, even though copies of the Treaty were still circulating throughout the country for Māori to sign.[44] With the signing of the Treaty and declaration of sovereignty the number of immigrants, particularly from the United Kingdom, began to increase.[45] +

      +
      +
      + Black and white engraving depicting a crowd of people +
      +
      + +
      A meeting of European and Māori inhabitants of Hawke's Bay Province. Engraving, 1863. +
      +
      +
      +

      + New Zealand, still part of the colony of New South Wales, became a separate Colony of New Zealand on 1 July 1841.[46] Armed conflict began between the Colonial government and Māori in 1843 with the Wairau Affray over land and disagreements over sovereignty. These conflicts, mainly in the North Island, saw thousands of Imperial troops and the Royal Navy come to New Zealand and became known as the New Zealand Wars. Following these armed conflicts, large amounts of Māori land was confiscated by the government to meet settler demands.[47] +

      +

      + The colony gained a representative government in 1852 and the first Parliament met in 1854.[48] In 1856 the colony effectively became self-governing, gaining responsibility over all domestic matters other than native policy.[48] (Control over native policy was granted in the mid-1860s.[48]) Following concerns that the South Island might form a separate colony, premier Alfred Domett moved a resolution to transfer the capital from Auckland to a locality near Cook Strait.[49] Wellington was chosen for its central location, with Parliament officially sitting there for the first time in 1865.[50] +

      +

      + In 1891 the Liberal Party came to power as the first organised political party.[51] The Liberal Government, led by Richard Seddon for most of its period in office,[52] passed many important social and economic measures. In 1893 New Zealand was the first nation in the world to grant all women the right to vote[51] and in 1894 pioneered the adoption of compulsory arbitration between employers and unions.[53] +

      +

      + In 1907, at the request of the New Zealand Parliament, King Edward VII proclaimed New Zealand a Dominion within the British Empire,[54] reflecting its self-governing status.[55] In 1947 the country adopted the Statute of Westminster, confirming that the British Parliament could no longer legislate for New Zealand without the consent of New Zealand.[48] +

      +

      + Early in the 20th century, New Zealand was involved in world affairs, fighting in the First and Second World Wars[56] and suffering through the Great Depression.[57] The depression led to the election of the First Labour Government and the establishment of a comprehensive welfare state and a protectionist economy.[58] New Zealand experienced increasing prosperity following the Second World War[59] and Māori began to leave their traditional rural life and move to the cities in search of work.[60] A Māori protest movement developed, which criticised Eurocentrism and worked for greater recognition of Māori culture and of the Treaty of Waitangi.[61] In 1975, a Waitangi Tribunal was set up to investigate alleged breaches of the Treaty, and it was enabled to investigate historic grievances in 1985.[41] The government has negotiated settlements of these grievances with many iwi,[62] although Māori claims to the foreshore and seabed have proved controversial in the 2000s.[63][64] +

      +

      + Government and politics +

      + +
      +
      +
      +
      +
      + The Queen wearing her New Zealand insignia +
      +
      + Elizabeth II, Queen of New Zealand +
      +
      +
      +
      + A smiling woman wearing a black dress +
      +
      + Jacinda Ardern, Prime Minister of New Zealand +
      +
      +
      +
      +
      +

      + New Zealand is a constitutional monarchy with a parliamentary democracy,[65] although its constitution is not codified.[66] Elizabeth II is the Queen of New Zealand[67] and thus the head of state.[68] The Queen is represented by the governor-general, whom she appoints on the advice of the prime minister.[69] The governor-general can exercise the Crown's prerogative powers, such as reviewing cases of injustice and making appointments of ministers, ambassadors and other key public officials,[70] and in rare situations, the reserve powers (e.g. the power to dissolve parliament or refuse the royal assent of a bill into law).[71] The powers of the monarch and the governor-general are limited by constitutional constraints and they cannot normally be exercised without the advice of ministers.[71] +

      +

      + The New Zealand Parliament holds legislative power and consists of the Queen and the House of Representatives.[72] It also included an upper house, the Legislative Council, until this was abolished in 1950.[72] The supremacy of parliament over the Crown and other government institutions was established in England by the Bill of Rights 1689 and has been ratified as law in New Zealand.[72] The House of Representatives is democratically elected and a government is formed from the party or coalition with the majority of seats. If no majority is formed, a minority government can be formed if support from other parties during confidence and supply votes is assured.[72] The governor-general appoints ministers under advice from the prime minister, who is by convention the parliamentary leader of the governing party or coalition.[73] Cabinet, formed by ministers and led by the prime minister, is the highest policy-making body in government and responsible for deciding significant government actions.[74] Members of Cabinet make major decisions collectively, and are therefore collectively responsible for the consequences of these decisions.[75] +

      +

      + A parliamentary general election must be called no later than three years after the previous election.[76] Almost all general elections between 1853 and 1993 were held under the first-past-the-post voting system.[77] Since the 1996 election, a form of proportional representation called mixed-member proportional (MMP) has been used.[66] Under the MMP system, each person has two votes; one is for a candidate standing in the voter's electorate and the other is for a party. Since the 2014 election, there have been 71 electorates (which include seven Māori electorates in which only Māori can optionally vote),[78] and the remaining 49 of the 120 seats are assigned so that representation in parliament reflects the party vote, with the threshold that a party must win at least one electorate or 5% of the total party vote before it is eligible for a seat.[79] +

      +
      +
      + A block of buildings fronted by a large statue. +
      +
      + +
      A statue of Richard Seddon, the "Beehive" (Executive Wing), and Parliament House (right), in Parliament Grounds, Wellington. +
      +
      +
      +

      + Elections since the 1930s have been dominated by two political parties, National and Labour.[77] Between March 2005 and August 2006, New Zealand became the first country in the world in which all the highest offices in the land—head of state, governor-general, prime minister, speaker and chief justice—were occupied simultaneously by women.[80] The current prime minister is Jacinda Ardern, who has been in office since 26 October 2017.[81] She is the country's third female prime minister.[82] +

      +

      + New Zealand's judiciary, headed by the chief justice,[83] includes the Supreme Court, Court of Appeal, the High Court, and subordinate courts.[84] Judges and judicial officers are appointed non-politically and under strict rules regarding tenure to help maintain judicial independence.[66] This theoretically allows the judiciary to interpret the law based solely on the legislation enacted by Parliament without other influences on their decisions.[85] +

      +

      + New Zealand is identified as one of the world's most stable and well-governed states.[86] As at 2017, the country was ranked fourth in the strength of its democratic institutions,[87] and first in government transparency and lack of corruption.[88] A 2017 Human Rights Report by the U.S. Department of State noted that the government generally respected the rights of individuals, but voiced concerns regarding the social status of the Māori population.[89] New Zealand ranks highly for civic participation in the political process, with 77% voter turnout during recent elections, compared to an OECD average of 69%.[90] +

      + +

      + Foreign relations and military +

      + +
      +
      + A squad of men kneel in the desert sand while performing a war dance +
      +
      + +
      Māori Battalion haka in Egypt, 1941 +
      +
      +
      +

      + Early colonial New Zealand allowed the British Government to determine external trade and be responsible for foreign policy.[91] The 1923 and 1926 Imperial Conferences decided that New Zealand should be allowed to negotiate its own political treaties and the first commercial treaty was ratified in 1928 with Japan. On 3 September 1939 New Zealand allied itself with Britain and declared war on Germany with Prime Minister Michael Joseph Savage proclaiming, "Where she goes, we go; where she stands, we stand."[92] +

      +

      + In 1951 the United Kingdom became increasingly focused on its European interests,[93] while New Zealand joined Australia and the United States in the ANZUS security treaty.[94] The influence of the United States on New Zealand weakened following protests over the Vietnam War,[95] the refusal of the United States to admonish France after the sinking of the Rainbow Warrior,[96] disagreements over environmental and agricultural trade issues and New Zealand's nuclear-free policy.[97][98] Despite the United States' suspension of ANZUS obligations the treaty remained in effect between New Zealand and Australia, whose foreign policy has followed a similar historical trend.[99] Close political contact is maintained between the two countries, with free trade agreements and travel arrangements that allow citizens to visit, live and work in both countries without restrictions.[100] In 2013 there were about 650,000 New Zealand citizens living in Australia, which is equivalent to 15% of the resident population of New Zealand.[101] +

      +
      +
      + A soldier in a green army uniform faces forwards +
      +
      + +
      Anzac Day service at the National War Memorial +
      +
      +
      +

      + New Zealand has a strong presence among the Pacific Island countries. A large proportion of New Zealand's aid goes to these countries and many Pacific people migrate to New Zealand for employment.[102] Permanent migration is regulated under the 1970 Samoan Quota Scheme and the 2002 Pacific Access Category, which allow up to 1,100 Samoan nationals and up to 750 other Pacific Islanders respectively to become permanent New Zealand residents each year. A seasonal workers scheme for temporary migration was introduced in 2007 and in 2009 about 8,000 Pacific Islanders were employed under it.[103] A regional power,[104] New Zealand is involved in the Pacific Islands Forum, the Pacific Community, Asia-Pacific Economic Cooperation and the Association of Southeast Asian Nations Regional Forum (including the East Asia Summit).[100] New Zealand is a member of the United Nations,[105] the Commonwealth of Nations[106] and the Organisation for Economic Co-operation and Development (OECD),[107] and participates in the Five Power Defence Arrangements.[108] +

      +

      + New Zealand's military services—the Defence Force—comprise the New Zealand Army, the Royal New Zealand Air Force and the Royal New Zealand Navy.[109] New Zealand's national defence needs are modest, since a direct attack is unlikely.[110] However, its military has had a global presence. The country fought in both world wars, with notable campaigns in Gallipoli, Crete,[111] El Alamein[112] and Cassino.[113] The Gallipoli campaign played an important part in fostering New Zealand's national identity[114][115] and strengthened the ANZAC tradition it shares with Australia.[116] +

      +

      + In addition to Vietnam and the two world wars, New Zealand fought in the Second Boer War,[117] the Korean War,[118] the Malayan Emergency,[119] the Gulf War and the Afghanistan War. It has contributed forces to several regional and global peacekeeping missions, such as those in Cyprus, Somalia, Bosnia and Herzegovina, the Sinai, Angola, Cambodia, the Iran–Iraq border, Bougainville, East Timor, and the Solomon Islands.[120] +

      +

      + Local government and external territories +

      + +
      +
      + Map with the North, South, Stewart/Rakiura, Tokelau, Cook, Niue, Kermadec, Chatham, Bounty, Antipodes, Snare, Auckland and Campbell Islands highlighted. New Zealand's segment of Antarctica (the Ross Dependency) is also highlighted. +
      +
      + +
      Locations of the countries and territories within the Realm of New Zealand +
      +
      +
      +

      + The early European settlers divided New Zealand into provinces, which had a degree of autonomy.[121] Because of financial pressures and the desire to consolidate railways, education, land sales and other policies, government was centralised and the provinces were abolished in 1876.[122] The provinces are remembered in regional public holidays[123] and sporting rivalries.[124] +

      +

      + Since 1876, various councils have administered local areas under legislation determined by the central government.[121][125] In 1989, the government reorganised local government into the current two-tier structure of regional councils and territorial authorities.[126] The 249 municipalities[126] that existed in 1975 have now been consolidated into 67 territorial authorities and 11 regional councils.[127] The regional councils' role is to regulate "the natural environment with particular emphasis on resource management",[126] while territorial authorities are responsible for sewage, water, local roads, building consents and other local matters.[128][129] Five of the territorial councils are unitary authorities and also act as regional councils.[129] The territorial authorities consist of 13 city councils, 53 district councils, and the Chatham Islands Council. While officially the Chatham Islands Council is not a unitary authority, it undertakes many functions of a regional council.[130] +

      +

      + The Realm of New Zealand, one of 16 Commonwealth realms,[131] is the entire area over which the Queen of New Zealand is sovereign, and comprises New Zealand, Tokelau, the Ross Dependency, the Cook Islands and Niue.[65] The Cook Islands and Niue are self-governing states in free association with New Zealand.[132][133] The New Zealand Parliament cannot pass legislation for these countries, but with their consent can act on behalf of them in foreign affairs and defence. Tokelau is classified as a non-self-governing territory, but is administered by a council of three elders (one from each Tokelauan atoll).[134] The Ross Dependency is New Zealand's territorial claim in Antarctica, where it operates the Scott Base research facility.[135] New Zealand nationality law treats all parts of the realm equally, so most people born in New Zealand, the Cook Islands, Niue, Tokelau and the Ross Dependency are New Zealand citizens.[136][n 7] +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

      + Environment +

      + +

      + Geography +

      + + +
      +
      + Islands of New Zealand as seen from satellite +
      +
      + +
      The snow-capped Southern Alps dominate the South Island, while the North Island's Northland Peninsula stretches towards the subtropics +
      +
      +
      +

      + New Zealand is located near the centre of the water hemisphere and is made up of two main islands and a number of smaller islands. The two main islands (the North Island, or Te Ika-a-Māui, and the South Island, or Te Waipounamu) are separated by Cook Strait, 22 kilometres (14 mi) wide at its narrowest point.[138] Besides the North and South Islands, the five largest inhabited islands are Stewart Island (across the Foveaux Strait), Chatham Island, Great Barrier Island (in the Hauraki Gulf),[139] D'Urville Island (in the Marlborough Sounds)[140] and Waiheke Island (about 22 km (14 mi) from central Auckland).[141] +

      + +
      +
      +
      +
      +
      + A large mountain with a lake in the foreground +
      +
      + Aoraki / Mount Cook is the highest point of New Zealand, at 3,754 metres +
      +
      +
      +
      +
      +
      + Snow-capped mountain range +
      +
      + The Southern Alps stretch for 500 kilometres down the South Island +
      +
      +
      +
      +
      +

      + New Zealand is long and narrow (over 1,600 kilometres (990 mi) along its north-north-east axis with a maximum width of 400 kilometres (250 mi)),[142] with about 15,000 km (9,300 mi) of coastline[143] and a total land area of 268,000 square kilometres (103,500 sq mi).[144] Because of its far-flung outlying islands and long coastline, the country has extensive marine resources. Its exclusive economic zone is one of the largest in the world, covering more than 15 times its land area.[145] +

      +

      + The South Island is the largest landmass of New Zealand. It is divided along its length by the Southern Alps.[146] There are 18 peaks over 3,000 metres (9,800 ft), the highest of which is Aoraki / Mount Cook at 3,754 metres (12,316 ft).[147] Fiordland's steep mountains and deep fiords record the extensive ice age glaciation of this southwestern corner of the South Island.[148] The North Island is less mountainous but is marked by volcanism.[149] The highly active Taupo Volcanic Zone has formed a large volcanic plateau, punctuated by the North Island's highest mountain, Mount Ruapehu (2,797 metres (9,177 ft)). The plateau also hosts the country's largest lake, Lake Taupo,[150] nestled in the caldera of one of the world's most active supervolcanoes.[151] +

      +

      + The country owes its varied topography, and perhaps even its emergence above the waves, to the dynamic boundary it straddles between the Pacific and Indo-Australian Plates.[152] New Zealand is part of Zealandia, a microcontinent nearly half the size of Australia that gradually submerged after breaking away from the Gondwanan supercontinent.[153] About 25 million years ago, a shift in plate tectonic movements began to contort and crumple the region. This is now most evident in the Southern Alps, formed by compression of the crust beside the Alpine Fault. Elsewhere the plate boundary involves the subduction of one plate under the other, producing the Puysegur Trench to the south, the Hikurangi Trench east of the North Island, and the Kermadec and Tonga Trenches[154] further north.[152] +

      +

      + New Zealand is part of a region known as Australasia, together with Australia.[155] It also forms the southwestern extremity of the geographic and ethnographic region called Polynesia.[156] The term Oceania is often used to denote the wider region encompassing the Australian continent, New Zealand and various islands in the Pacific Ocean that are not included in the seven-continent model.[157] +

      +
      + +

      + Climate +

      + +

      + New Zealand's climate is predominantly temperate maritime (Köppen: Cfb), with mean annual temperatures ranging from 10 °C (50 °F) in the south to 16 °C (61 °F) in the north.[158] Historical maxima and minima are 42.4 °C (108.32 °F) in Rangiora, Canterbury and −25.6 °C (−14.08 °F) in Ranfurly, Otago.[159] Conditions vary sharply across regions from extremely wet on the West Coast of the South Island to almost semi-arid in Central Otago and the Mackenzie Basin of inland Canterbury and subtropical in Northland.[160] Of the seven largest cities, Christchurch is the driest, receiving on average only 640 millimetres (25 in) of rain per year and Wellington the wettest, receiving almost twice that amount.[161] Auckland, Wellington and Christchurch all receive a yearly average of more than 2,000 hours of sunshine. The southern and southwestern parts of the South Island have a cooler and cloudier climate, with around 1,400–1,600 hours; the northern and northeastern parts of the South Island are the sunniest areas of the country and receive about 2,400–2,500 hours.[162] The general snow season is early June until early October, though cold snaps can occur outside this season.[163] Snowfall is common in the eastern and southern parts of the South Island and mountain areas across the country.[158] +

      +

      + The table below lists climate normals for the warmest and coldest months in New Zealand's six largest cities. North Island cities are generally warmest in February. South Island cities are warmest in January. +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + Average daily maximum and minimum temperatures for the six largest cities of New Zealand[164] +
      + Location + + Jan/Feb (°C) + + Jan/Feb (°F) + + July (°C) + + July (°F) +
      + Auckland + + 23/16 + + 74/60 + + 14/7 + + 58/45 +
      + Wellington + + 20/13 + + 68/56 + + 11/6 + + 52/42 +
      + Christchurch + + 22/12 + + 72/53 + + 10/0 + + 51/33 +
      + Hamilton + + 24/13 + + 75/56 + + 14/4 + + 57/39 +
      + Tauranga + + 24/15 + + 75/59 + + 14/6 + + 58/42 +
      + Dunedin + + 19/11 + + 66/53 + + 10/3 + + 50/37 +
      +

      + Biodiversity +

      + +
      +
      + Kiwi amongst sticks +
      +
      + +
      The endemic flightless kiwi is a national icon. +
      +
      +
      +

      + New Zealand's geographic isolation for 80 million years[165] and island biogeography has influenced evolution of the country's species of animals, fungi and plants. Physical isolation has caused biological isolation, resulting in a dynamic evolutionary ecology with examples of very distinctive plants and animals as well as populations of widespread species.[166][167] About 82% of New Zealand's indigenous vascular plants are endemic, covering 1,944 species across 65 genera.[168][169] The number of fungi recorded from New Zealand, including lichen-forming species, is not known, nor is the proportion of those fungi which are endemic, but one estimate suggests there are about 2,300 species of lichen-forming fungi in New Zealand[168] and 40% of these are endemic.[170] The two main types of forest are those dominated by broadleaf trees with emergent podocarps, or by southern beech in cooler climates.[171] The remaining vegetation types consist of grasslands, the majority of which are tussock.[172] +

      +

      + Before the arrival of humans, an estimated 80% of the land was covered in forest, with only high alpine, wet, infertile and volcanic areas without trees.[173] Massive deforestation occurred after humans arrived, with around half the forest cover lost to fire after Polynesian settlement.[174] Much of the remaining forest fell after European settlement, being logged or cleared to make room for pastoral farming, leaving forest occupying only 23% of the land.[175] +

      +
      +
      + An artist's rendition of a Haast's eagle attacking two moa +
      +
      + +
      The giant Haast's eagle died out when humans hunted its main prey, the moa, to extinction. +
      +
      +
      +

      + The forests were dominated by birds, and the lack of mammalian predators led to some like the kiwi, kakapo, weka and takahē evolving flightlessness.[176] The arrival of humans, associated changes to habitat, and the introduction of rats, ferrets and other mammals led to the extinction of many bird species, including large birds like the moa and Haast's eagle.[177][178] +

      +

      + Other indigenous animals are represented by reptiles (tuatara, skinks and geckos), frogs,[179] spiders,[180] insects (weta)[181] and snails.[182] Some, such as the tuatara, are so unique that they have been called living fossils.[183] Three species of bats (one since extinct) were the only sign of native land mammals in New Zealand until the 2006 discovery of bones from a unique, mouse-sized land mammal at least 16 million years old.[184][185] Marine mammals however are abundant, with almost half the world's cetaceans (whales, dolphins, and porpoises) and large numbers of fur seals reported in New Zealand waters.[186] Many seabirds breed in New Zealand, a third of them unique to the country.[187] More penguin species are found in New Zealand than in any other country.[188] +

      +

      + Since human arrival, almost half of the country's vertebrate species have become extinct, including at least fifty-one birds, three frogs, three lizards, one freshwater fish, and one bat. Others are endangered or have had their range severely reduced.[177] However, New Zealand conservationists have pioneered several methods to help threatened wildlife recover, including island sanctuaries, pest control, wildlife translocation, fostering, and ecological restoration of islands and other selected areas.[189][190][191][192] +

      +
      +

      + Economy +

      + + +
      +
      + Boats docked in blue-green water. Plate glass skyscrapers rising up in the background. +
      +
      + +
      Waterfront along Auckland CBD, a major hub of economic activity +
      +
      +
      +

      + New Zealand has an advanced market economy,[193] ranked 16th in the 2018 Human Development Index[8] and third in the 2018 Index of Economic Freedom.[194] It is a high-income economy with a nominal gross domestic product (GDP) per capita of US$36,254.[6] The currency is the New Zealand dollar, informally known as the "Kiwi dollar"; it also circulates in the Cook Islands (see Cook Islands dollar), Niue, Tokelau, and the Pitcairn Islands.[195] +

      +

      + Historically, extractive industries have contributed strongly to New Zealand's economy, focussing at different times on sealing, whaling, flax, gold, kauri gum, and native timber.[196] The first shipment of refrigerated meat on the Dunedin in 1882 led to the establishment of meat and dairy exports to Britain, a trade which provided the basis for strong economic growth in New Zealand.[197] High demand for agricultural products from the United Kingdom and the United States helped New Zealanders achieve higher living standards than both Australia and Western Europe in the 1950s and 1960s.[198] In 1973, New Zealand's export market was reduced when the United Kingdom joined the European Economic Community[199] and other compounding factors, such as the 1973 oil and 1979 energy crises, led to a severe economic depression.[200] Living standards in New Zealand fell behind those of Australia and Western Europe, and by 1982 New Zealand had the lowest per-capita income of all the developed nations surveyed by the World Bank.[201] In the mid-1980s New Zealand deregulated its agricultural sector by phasing out subsidies over a three-year period.[202][203] Since 1984, successive governments engaged in major macroeconomic restructuring (known first as Rogernomics and then Ruthanasia), rapidly transforming New Zealand from a protected and highly regulated economy to a liberalised free-trade economy.[204][205] +

      +
      +
      + Blue water against a backdrop of snow-capped mountains +
      +
      + +
      Milford Sound is one of New Zealand's most famous tourist destinations.[206] +
      +
      +
      +

      + Unemployment peaked above 10% in 1991 and 1992,[207] following the 1987 share market crash, but eventually fell to a record low (since 1986) of 3.7% in 2007 (ranking third from twenty-seven comparable OECD nations).[207] However, the global financial crisis that followed had a major impact on New Zealand, with the GDP shrinking for five consecutive quarters, the longest recession in over thirty years,[208][209] and unemployment rising back to 7% in late 2009.[210] Unemployment rates for different age groups follow similar trends, but are consistently higher among youth. In the December 2014 quarter, the general unemployment rate was around 5.8%, while the unemployment rate for youth aged 15 to 21 was 15.6%.[207] New Zealand has experienced a series of "brain drains" since the 1970s[211] that still continue today.[212] Nearly one quarter of highly skilled workers live overseas, mostly in Australia and Britain, which is the largest proportion from any developed nation.[213] In recent decades, however, a "brain gain" has brought in educated professionals from Europe and less developed countries.[214][215] Today New Zealand's economy benefits from a high level of innovation.[216] +

      +

      + Trade +

      +

      + New Zealand is heavily dependent on international trade,[217] particularly in agricultural products.[218] Exports account for 24% of its output,[143] making New Zealand vulnerable to international commodity prices and global economic slowdowns. Food products made up 55% of the value of all the country's exports in 2014; wood was the second largest earner (7%).[219] New Zealand's main trading partners, as at June 2018, are China (NZ$27.8b), Australia ($26.2b), the European Union ($22.9b), the United States ($17.6b), and Japan ($8.4b).[220] On 7 April 2008, New Zealand and China signed the New Zealand–China Free Trade Agreement, the first such agreement China has signed with a developed country.[221] The service sector is the largest sector in the economy, followed by manufacturing and construction and then farming and raw material extraction.[143] Tourism plays a significant role in the economy, contributing $12.9 billion (or 5.6%) to New Zealand's total GDP and supporting 7.5% of the total workforce in 2016.[222] International visitor arrivals are expected to increase at a rate of 5.4% annually up to 2022.[222] +

      +
      +
      + A Romney ewe with her two lambs +
      +
      + +
      Wool has historically been one of New Zealand's major exports. +
      +
      +
      +

      + Wool was New Zealand's major agricultural export during the late 19th century.[196] Even as late as the 1960s it made up over a third of all export revenues,[196] but since then its price has steadily dropped relative to other commodities[223] and wool is no longer profitable for many farmers.[224] In contrast dairy farming increased, with the number of dairy cows doubling between 1990 and 2007,[225] to become New Zealand's largest export earner.[226] In the year to June 2018, dairy products accounted for 17.7% ($14.1 billion) of total exports,[220] and the country's largest company, Fonterra, controls almost one-third of the international dairy trade.[227] Other exports in 2017-18 were meat (8.8%), wood and wood products (6.2%), fruit (3.6%), machinery (2.2%) and wine (2.1%).[220] New Zealand's wine industry has followed a similar trend to dairy, the number of vineyards doubling over the same period,[228] overtaking wool exports for the first time in 2007.[229][230] +

      +

      + Infrastructure +

      +
      +
      + A mid-size jet airliner in flight. The plane livery is all-black and features a New Zealand silver fern mark. +
      +
      + +
      A Boeing 787-9 Dreamliner of Air New Zealand, the flag carrier of New Zealand +
      +
      +
      +

      + In 2015, renewable energy, primarily geothermal and hydroelectric power, generated 40.1% of New Zealand's gross energy supply.[231] Geothermal power alone accounted for 22% of New Zealand's energy in 2015.[231] +

      +

      + The provision of water supply and sanitation is generally of good quality. Regional authorities provide water abstraction, treatment and distribution infrastructure to most developed areas.[232][233] +

      +

      + New Zealand's transport network comprises 94,000 kilometres (58,410 mi) of roads, including 199 kilometres (124 mi) of motorways,[234] and 4,128 kilometres (2,565 mi) of railway lines.[143] Most major cities and towns are linked by bus services, although the private car is the predominant mode of transport.[235] The railways were privatised in 1993, but were re-nationalised by the government in stages between 2004 and 2008. The state-owned enterprise KiwiRail now operates the railways, with the exception of commuter services in Auckland and Wellington which are operated by Transdev[236] and Metlink,[237] respectively. Railways run the length of the country, although most lines now carry freight rather than passengers.[238] Most international visitors arrive via air[239] and New Zealand has six international airports, but currently only the Auckland and Christchurch airports connect directly with countries other than Australia or Fiji.[240] +

      +

      + The New Zealand Post Office had a monopoly over telecommunications in New Zealand until 1987 when Telecom New Zealand was formed, initially as a state-owned enterprise and then privatised in 1990.[241] Chorus, which was split from Telecom (now Spark) in 2011,[242] still owns the majority of the telecommunications infrastructure, but competition from other providers has increased.[241] A large-scale rollout of gigabit-capable fibre to the premises, branded as Ultra-Fast Broadband, began in 2009 with a target of being available to 87% of the population by 2022.[243] As of 2017, the United Nations International Telecommunication Union ranks New Zealand 13th in the development of information and communications infrastructure.[244] +

      +

      + Demography +

      + +
      +
      + Stationary population pyramid broken down into 21 age ranges. +
      +
      + +
      Population pyramid (2017) +
      +
      +
      +

      + The 2013 New Zealand census enumerated a resident population of 4,242,048, an increase of 5.3% over the 2006 figure.[245][n 8] As of September 2019, the total population has risen to an estimated 4,933,210.[5] +

      +

      + New Zealand is a predominantly urban country, with 73.0% of the population living in the seventeen main urban areas (i.e. population 30,000 or greater) and 55.1% living in the four largest cities of Auckland, Christchurch, Wellington, and Hamilton.[247] New Zealand cities generally rank highly on international livability measures. For instance, in 2016 Auckland was ranked the world's third most liveable city and Wellington the twelfth by the Mercer Quality of Living Survey.[248] +

      +

      + Life expectancy for New Zealanders in 2012 was 84 years for females, and 80.2 years for males.[249] Life expectancy at birth is forecast to increase from 80 years to 85 years in 2050 and infant mortality is expected to decline.[250] New Zealand's fertility rate of 2.1 is relatively high for a developed country, and natural births account for a significant proportion of population growth. Consequently, the country has a young population compared to most industrialised nations, with 20% of New Zealanders being 14 years old or younger.[143] In 2018 the median age of the New Zealand population was 38.1 years.[251] By 2050 the median age is projected to rise to 43 years and the percentage of people 60 years of age and older to rise from 18% to 29%.[250] In 2008 the leading cause of premature death was cancer, at 29.8%, followed by ischaemic heart disease, 19.7%, and then cerebrovascular disease, 9.2%.[252] As of 2016, total expenditure on health care (including private sector spending) is 9.2% of GDP.[253]
      +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

      +
      +

      +

      + Ethnicity and immigration +

      + +
      +
      + Pedestrians crossing a wide street which is flanked by storefronts +
      +
      + +
      Pedestrians on Queen Street in Auckland, an ethnically diverse city +
      +
      +
      +

      + In the 2013 census, 74.0% of New Zealand residents identified ethnically as European, and 14.9% as Māori. Other major ethnic groups include Asian (11.8%) and Pacific peoples (7.4%), two-thirds of whom live in the Auckland Region.[255][n 3] The population has become more diverse in recent decades: in 1961, the census reported that the population of New Zealand was 92% European and 7% Māori, with Asian and Pacific minorities sharing the remaining 1%.[256] +

      +

      + While the demonym for a New Zealand citizen is New Zealander, the informal "Kiwi" is commonly used both internationally[257] and by locals.[258] The Māori loanword Pākehā has been used to refer to New Zealanders of European descent, although others reject this appellation.[259][260] The word Pākehā today is increasingly used to refer to all non-Polynesian New Zealanders.[261] +

      +

      + The Māori were the first people to reach New Zealand, followed by the early European settlers. Following colonisation, immigrants were predominantly from Britain, Ireland and Australia because of restrictive policies similar to the White Australia policy.[262] There was also significant Dutch, Dalmatian,[263] German, and Italian immigration, together with indirect European immigration through Australia, North America, South America and South Africa.[264][265] Net migration increased after the Second World War; in the 1970s and 1980s policies were relaxed and immigration from Asia was promoted.[265][266] In 2009–10, an annual target of 45,000–50,000 permanent residence approvals was set by the New Zealand Immigration Service—more than one new migrant for every 100 New Zealand residents.[267] Just over 25% of New Zealand's population was born overseas, with the majority (52%) living in the Auckland Region. The United Kingdom remains the largest source of New Zealand's overseas population, with a quarter of all overseas-born New Zealanders born there; other major sources of New Zealand's overseas-born population are China, India, Australia, South Africa, Fiji and Samoa.[268] The number of fee-paying international students increased sharply in the late 1990s, with more than 20,000 studying in public tertiary institutions in 2002.[269] +

      +

      + Language +

      + +
      +
      + Map of New Zealand showing the percentage of people in each census area unit who speak Māori. Areas of the North Island exhibit the highest Māori proficiency. +
      +
      + +
      Speakers of Māori according to the 2013 census[270] +
      +   Less than 5% +
      +
      +   More than 5% +
      +
      +   More than 10% +
      +
      +   More than 20% +
      +
      +   More than 30% +
      +
      +   More than 40% +
      +
      +   More than 50% +
      +
      +
      +
      +

      + English is the predominant language in New Zealand, spoken by 96.1% of the population.[271] New Zealand English is similar to Australian English and many speakers from the Northern Hemisphere are unable to tell the accents apart.[272] The most prominent differences between the New Zealand English dialect and other English dialects are the shifts in the short front vowels: the short-"i" sound (as in "kit") has centralised towards the schwa sound (the "a" in "comma" and "about"); the short-"e" sound (as in "dress") has moved towards the short-"i" sound; and the short-"a" sound (as in "trap") has moved to the short-"e" sound.[273] +

      +

      + After the Second World War, Māori were discouraged from speaking their own language (te reo Māori) in schools and workplaces and it existed as a community language only in a few remote areas.[274] It has recently undergone a process of revitalisation,[275] being declared one of New Zealand's official languages in 1987,[276] and is spoken by 3.7% of the population.[271][n 9] There are now Māori language immersion schools and two television channels that broadcast predominantly in Māori.[278] Many places have both their Māori and English names officially recognised.[279] +

      +

      + As recorded in the 2013 census,[271] Samoan is the most widely spoken non-official language (2.2%),[n 10] followed by Hindi (1.7%), "Northern Chinese" (including Mandarin, 1.3%) and French (1.2%). 20,235 people (0.5%) reported the ability to use New Zealand Sign Language. It was declared one of New Zealand's official languages in 2006.[280] +

      +

      + Religion +

      + + +
      +
      + Simple white building with two red domed towers +
      +
      + +
      A Rātana church on a hill near Raetihi. The two-tower construction is characteristic of Rātana buildings. +
      +
      +
      +

      + Christianity is the predominant religion in New Zealand, although its society is among the most secular in the world.[281][282] In the 2018 census, 51.4% of the population identified with one or more religions, including 38.6% identifying as Christians. Another 48.6% indicated that they had no religion.[n 11][283] The main Christian denominations are, by number of adherents, Roman Catholicism (10.1%), Anglicanism (6.8%), Presbyterianism (5.5%) and "Christian not further defined" (i.e. people identifying as Christian but not stating the denomination, 6.6%).[283] The Māori-based Ringatū and Rātana religions (1.3%) are also Christian in origin.[284][285] Immigration and demographic change in recent decades has contributed to the growth of minority religions,[286] such as Hinduism (2.6%), Buddhism (1.1%), Islam (1.3%) and Sikhism (0.5%).[284] The Auckland Region exhibited the greatest religious diversity.[284] +

      +

      + Education +

      + +

      + Primary and secondary schooling is compulsory for children aged 6 to 16, with the majority attending from the age of 5.[287] There are 13 school years and attending state (public) schools is free to New Zealand citizens and permanent residents from a person's 5th birthday to the end of the calendar year following their 19th birthday.[288] New Zealand has an adult literacy rate of 99%,[143] and over half of the population aged 15 to 29 hold a tertiary qualification.[287] There are five types of government-owned tertiary institutions: universities, colleges of education, polytechnics, specialist colleges, and wānanga,[289] in addition to private training establishments.[290] In the adult population 14.2% have a bachelor's degree or higher, 30.4% have some form of secondary qualification as their highest qualification and 22.4% have no formal qualification.[291] The OECD's Programme for International Student Assessment ranks New Zealand's education system as the seventh best in the world, with students performing exceptionally well in reading, mathematics and science.[292] +

      +
      +

      + Culture +

      + +
      +
      +
      + Tall wooden carving showing Kupe above two tentacled sea creatures +
      +
      +
      + +
      Late 20th-century house-post depicting the navigator Kupe fighting two sea creatures +
      +
      +
      +

      + Early Māori adapted the tropically based east Polynesian culture in line with the challenges associated with a larger and more diverse environment, eventually developing their own distinctive culture. Social organisation was largely communal with families (whānau), subtribes (hapū) and tribes (iwi) ruled by a chief (rangatira), whose position was subject to the community's approval.[293] The British and Irish immigrants brought aspects of their own culture to New Zealand and also influenced Māori culture,[294][295] particularly with the introduction of Christianity.[296] However, Māori still regard their allegiance to tribal groups as a vital part of their identity, and Māori kinship roles resemble those of other Polynesian peoples.[297] More recently American, Australian, Asian and other European cultures have exerted influence on New Zealand. Non-Māori Polynesian cultures are also apparent, with Pasifika, the world's largest Polynesian festival, now an annual event in Auckland.[298] +

      +

      + The largely rural life in early New Zealand led to the image of New Zealanders being rugged, industrious problem solvers.[299] Modesty was expected and enforced through the "tall poppy syndrome", where high achievers received harsh criticism.[300] At the time New Zealand was not known as an intellectual country.[301] From the early 20th century until the late 1960s, Māori culture was suppressed by the attempted assimilation of Māori into British New Zealanders.[274] In the 1960s, as tertiary education became more available and cities expanded[302] urban culture began to dominate.[303] However, rural imagery and themes are common in New Zealand's art, literature and media.[304] +

      +

      + New Zealand's national symbols are influenced by natural, historical, and Māori sources. The silver fern is an emblem appearing on army insignia and sporting team uniforms.[305] Certain items of popular culture thought to be unique to New Zealand are called "Kiwiana".[305] +

      +

      + Art +

      + +

      + As part of the resurgence of Māori culture, the traditional crafts of carving and weaving are now more widely practised and Māori artists are increasing in number and influence.[306] Most Māori carvings feature human figures, generally with three fingers and either a natural-looking, detailed head or a grotesque head.[307] Surface patterns consisting of spirals, ridges, notches and fish scales decorate most carvings.[308] The pre-eminent Māori architecture consisted of carved meeting houses (wharenui) decorated with symbolic carvings and illustrations. These buildings were originally designed to be constantly rebuilt, changing and adapting to different whims or needs.[309] +

      +

      + Māori decorated the white wood of buildings, canoes and cenotaphs using red (a mixture of red ochre and shark fat) and black (made from soot) paint and painted pictures of birds, reptiles and other designs on cave walls.[310] Māori tattoos (moko) consisting of coloured soot mixed with gum were cut into the flesh with a bone chisel.[311] Since European arrival paintings and photographs have been dominated by landscapes, originally not as works of art but as factual portrayals of New Zealand.[312] Portraits of Māori were also common, with early painters often portraying them as "noble savages", exotic beauties or friendly natives.[312] The country's isolation delayed the influence of European artistic trends allowing local artists to develop their own distinctive style of regionalism.[313] During the 1960s and 1970s many artists combined traditional Māori and Western techniques, creating unique art forms.[314] New Zealand art and craft has gradually achieved an international audience, with exhibitions in the Venice Biennale in 2001 and the "Paradise Now" exhibition in New York in 2004.[306][315] +

      +
      +
      + Refer to caption +
      +
      + +
      Portrait of Hinepare of Ngāti Kahungunu by Gottfried Lindauer, showing chin moko, pounamu hei-tiki and woven cloak +
      +
      +
      +

      + Māori cloaks are made of fine flax fibre and patterned with black, red and white triangles, diamonds and other geometric shapes.[316] Greenstone was fashioned into earrings and necklaces, with the most well-known design being the hei-tiki, a distorted human figure sitting cross-legged with its head tilted to the side.[317] Europeans brought English fashion etiquette to New Zealand, and until the 1950s most people dressed up for social occasions.[318] Standards have since relaxed and New Zealand fashion has received a reputation for being casual, practical and lacklustre.[319][320] However, the local fashion industry has grown significantly since 2000, doubling exports and increasing from a handful to about 50 established labels, with some labels gaining international recognition.[320] +

      +

      + Literature +

      + +

      + Māori quickly adopted writing as a means of sharing ideas, and many of their oral stories and poems were converted to the written form.[321] Most early English literature was obtained from Britain and it was not until the 1950s when local publishing outlets increased that New Zealand literature started to become widely known.[322] Although still largely influenced by global trends (modernism) and events (the Great Depression), writers in the 1930s began to develop stories increasingly focused on their experiences in New Zealand. During this period literature changed from a journalistic activity to a more academic pursuit.[323] Participation in the world wars gave some New Zealand writers a new perspective on New Zealand culture and with the post-war expansion of universities local literature flourished.[324] Dunedin is a UNESCO City of Literature.[325] +

      +

      + Media and entertainment +

      + +

      + New Zealand music has been influenced by blues, jazz, country, rock and roll and hip hop, with many of these genres given a unique New Zealand interpretation.[326] Māori developed traditional chants and songs from their ancient Southeast Asian origins, and after centuries of isolation created a unique "monotonous" and "doleful" sound.[327] Flutes and trumpets were used as musical instruments[328] or as signalling devices during war or special occasions.[329] Early settlers brought over their ethnic music, with brass bands and choral music being popular, and musicians began touring New Zealand in the 1860s.[330][331] Pipe bands became widespread during the early 20th century.[332] The New Zealand recording industry began to develop from 1940 onwards and many New Zealand musicians have obtained success in Britain and the United States.[326] Some artists release Māori language songs and the Māori tradition-based art of kapa haka (song and dance) has made a resurgence.[333] The New Zealand Music Awards are held annually by Recorded Music NZ; the awards were first held in 1965 by Reckitt & Colman as the Loxene Golden Disc awards.[334] Recorded Music NZ also publishes the country's official weekly record charts.[335] +

      +
      +
      + Hills with inset, round doors. Reflected in water. +
      +
      + +
      The Hobbiton Movie Set, located near Matamata, was used for The Lord of the Rings film trilogy.[336] +
      +
      +
      +

      + Public radio was introduced in New Zealand in 1922.[337] A state-owned television service began in 1960.[338] Deregulation in the 1980s saw a sudden increase in the numbers of radio and television stations.[339] New Zealand television primarily broadcasts American and British programming, along with a large number of Australian and local shows.[340] The number of New Zealand films significantly increased during the 1970s. In 1978 the New Zealand Film Commission started assisting local film-makers and many films attained a world audience, some receiving international acknowledgement.[339] The highest-grossing New Zealand films are Hunt for the Wilderpeople, Boy, The World's Fastest Indian, Once Were Warriors and Whale Rider.[341] The country's diverse scenery and compact size, plus government incentives,[342] have encouraged some producers to shoot big-budget productions in New Zealand, including Avatar, The Lord of the Rings, The Hobbit, The Chronicles of Narnia, King Kong and The Last Samurai.[343] The New Zealand media industry is dominated by a small number of companies, most of which are foreign-owned, although the state retains ownership of some television and radio stations.[344] Since 1994, Freedom House has consistently ranked New Zealand's press freedom in the top twenty, with the 19th freest media in 2015.[345] +

      +
      +

      + Sports +

      + +
      +
      + Rugby team wearing all black, facing the camera, knees bent, and facing toward a team wearing white +
      +
      + +
      A haka performed by the national rugby union team before a game. The haka is a challenge with vigorous movements and stamping of the feet. +
      +
      +
      +

      + Most of the major sporting codes played in New Zealand have British origins.[346] Rugby union is considered the national sport[347] and attracts the most spectators.[348] Golf, netball, tennis and cricket have the highest rates of adult participation, while netball, rugby union and football (soccer) are particularly popular among young people.[348][349] Around 54% of New Zealand adolescents participate in sports for their school.[349] Victorious rugby tours to Australia and the United Kingdom in the late 1880s and the early 1900s played an early role in instilling a national identity.[350] Horseracing was also a popular spectator sport and became part of the "Rugby, Racing and Beer" culture during the 1960s.[351] Māori participation in European sports was particularly evident in rugby and the country's team performs a haka, a traditional Māori challenge, before international matches.[352] New Zealand is known for its extreme sports, adventure tourism[353] and strong mountaineering tradition, as seen in the success of notable New Zealander Sir Edmund Hillary.[354][355] Other outdoor pursuits such as cycling, fishing, swimming, running, tramping, canoeing, hunting, snowsports, surfing and sailing are also popular.[356] The Polynesian sport of waka ama racing has experienced a resurgence of interest in New Zealand since the 1980s.[357] +

      +

      + New Zealand has competitive international teams in rugby union, rugby league, netball, cricket, softball, and sailing. New Zealand participated at the Summer Olympics in 1908 and 1912 as a joint team with Australia, before first participating on its own in 1920.[358] The country has ranked highly on a medals-to-population ratio at recent Games.[359][360] The "All Blacks", the national rugby union team, are the most successful in the history of international rugby[361] and the reigning World Cup champions.[362] +

      +

      + Cuisine +

      + +
      +
      + Raw meat and vegetables +
      +
      + +
      Ingredients to be prepared for a hāngi +
      +
      +
      +

      + The national cuisine has been described as Pacific Rim, incorporating the native Māori cuisine and diverse culinary traditions introduced by settlers and immigrants from Europe, Polynesia and Asia.[363] New Zealand yields produce from land and sea—most crops and livestock, such as maize, potatoes and pigs, were gradually introduced by the early European settlers.[364] Distinctive ingredients or dishes include lamb, salmon, kōura (crayfish),[365] dredge oysters, whitebait, pāua (abalone), mussels, scallops, pipis and tuatua (both are types of New Zealand shellfish),[366] kūmara (sweet potato), kiwifruit, tamarillo and pavlova (considered a national dish).[367][363] A hāngi is a traditional Māori method of cooking food using heated rocks buried in a pit oven. After European colonisation, Māori began cooking with pots and ovens and the hāngi was used less frequently, although it is still used for formal occasions such as tangihanga.[368] +

      +
      +

      + See also +

      + + +
      +

      + Footnotes +

      +
      +
        +
      1. + ^ "God Save the Queen" is officially a national anthem but is generally used only on regal and viceregal occasions.[1] +
      2. +
      3. + ^ English is a de facto official language due to its widespread use.[2] +
      4. +
      5. + ^ a b Ethnicity figures add to more than 100% as people could choose more than one ethnic group. +
      6. +
      7. + ^ The proportion of New Zealand's area (excluding estuaries) covered by rivers, lakes and ponds, based on figures from the New Zealand Land Cover Database,[4] is (357526 + 81936) / (26821559 – 92499–26033 – 19216) = 1.6%. If estuarine open water, mangroves, and herbaceous saline vegetation are included, the figure is 2.2%. +
      8. +
      9. + ^ The Chatham Islands have a separate time zone, 45 minutes ahead of the rest of New Zealand. +
      10. +
      11. + ^ Clocks are advanced by an hour from the last Sunday in September until the first Sunday in April.[9] Daylight saving time is also observed in the Chatham Islands, 45 minutes ahead of NZDT. +
      12. +
      13. + ^ A person born on or after 1 January 2006 acquires New Zealand citizenship at birth only if at least one parent is a New Zealand citizen or permanent resident. People born on or before 31 December 2005 acquired citizenship at birth (jus soli).[137] +
      14. +
      15. + ^ The population is increasing at a rate of 1.4–2.0% per year and is projected to rise to 5.01–5.51 million in 2025.[246] +
      16. +
      17. + ^ In 2015, 55% of Māori adults (aged 15 years and over) reported knowledge of te reo Māori. Of these speakers, 64% use Māori at home and 50,000 can speak the language "very well" or "well".[277] +
      18. +
      19. + ^ Of the 86,403 people that replied they spoke Samoan, 51,336 lived in the Auckland Region. +
      20. +
      21. + ^ Religion percentages may not add to 100% as people could claim multiple religions or object to answering the question. +
      22. +
      +
      +

      + Citations +

      +
      +
        +
      1. + ^ "Protocol for using New Zealand's National Anthems". Ministry for Culture and Heritage. Retrieved 17 February 2008. +
      2. +
      3. + ^ New Zealand Government (21 December 2007). International Covenant on Civil and Political Rights Fifth Periodic Report of the Government of New Zealand (PDF) (Report). p. 89. Archived from the original (PDF) on 24 January 2015. Retrieved 18 November 2015. In addition to the Māori language, New Zealand Sign Language is also an official language of New Zealand. The New Zealand Sign Language Act 2006 permits the use of NZSL in legal proceedings, facilitates competency standards for its interpretation and guides government departments in its promotion and use. English, the medium for teaching and learning in most schools, is a de facto official language by virtue of its widespread use. For these reasons, these three languages have special mention in the New Zealand Curriculum. + +
      4. +
      5. + ^ "2018 Census population and dwelling counts". Statistics New Zealand. Retrieved 26 September 2019. + +
      6. +
      7. + ^ "The New Zealand Land Cover Database". New Zealand Land Cover Database 2. Ministry for the Environment. 1 July 2009. Retrieved 26 April 2011. + +
      8. +
      9. + ^ a b "Population clock". Statistics New Zealand. Retrieved 14 April 2016. + The population estimate shown is automatically calculated daily at 00:00 UTC and is based on data obtained from the population clock on the date shown in the citation. +
      10. +
      11. + ^ a b c d e "New Zealand". International Monetary Fund. Retrieved 9 October 2018. + +
      12. +
      13. + ^ "Income inequality". Statistics New Zealand. Retrieved 14 June 2015. + +
      14. +
      15. + ^ a b "Human Development Report 2018" (PDF). HDRO (Human Development Report Office) United Nations Development Programme. p. 22. Retrieved 14 September 2018. + +
      16. +
      17. + ^ "New Zealand Daylight Time Order 2007 (SR 2007/185)". New Zealand Parliamentary Counsel Office. 6 July 2007. Retrieved 6 March 2017. + +
      18. +
      19. + ^ There is no official all-numeric date format for New Zealand, but government recommendations generally follow Australian date and time notation. See "The Govt.nz style guide", New Zealand Government, 9 December 2016, retrieved 7 March 2019 Italic or bold markup not allowed in: |website= (help) + . +
      20. +
      21. + ^ Tasman, Abel. "JOURNAL or DESCRIPTION By me Abel Jansz Tasman, Of a Voyage from Batavia for making Discoveries of the Unknown South Land in the year 1642". Project Gutenberg Australia. Retrieved 26 March 2018. + +
      22. +
      23. + ^ Wilson, John (March 2009). "European discovery of New Zealand – Tasman's achievement". Te Ara: The Encyclopedia of New Zealand. Retrieved 24 January 2011. + +
      24. +
      25. + ^ John Bathgate. "The Pamphlet Collection of Sir Robert Stout:Volume 44. Chapter 1, Discovery and Settlement". NZETC. Retrieved 17 August 2018. He named the country Staaten Land, in honour of the States-General of Holland, in the belief that it was part of the great southern continent. + +
      26. +
      27. + ^ Wilson, John (September 2007). "Tasman's achievement". Te Ara: The Encyclopedia of New Zealand. Retrieved 16 February 2008. + +
      28. +
      29. + ^ Mackay, Duncan (1986). "The Search For The Southern Land". In Fraser, B (ed.). The New Zealand Book Of Events. Auckland: Reed Methuen. pp. 52–54. + +
      30. +
      31. + ^ a b McKinnon, Malcolm (November 2009). "Place names – Naming the country and the main islands". Te Ara: The Encyclopedia of New Zealand. Retrieved 24 January 2011. + +
      32. +
      33. + ^ King 2003, p. 41. +
      34. +
      35. + ^ Hay, Maclagan & Gordon 2008, p. 72. +
      36. +
      37. + ^ a b Mein Smith 2005, p. 6. +
      38. +
      39. + ^ Brunner, Thomas (1851). The Great Journey: an expedition to explore the interior of the Middle Island, New Zealand, 1846-8. Royal Geographical Society. + +
      40. +
      41. + ^ a b Williamson, Maurice (10 October 2013). "Names of NZ's two main islands formalised" (Press release). New Zealand Government. Retrieved 1 May 2017. + +
      42. +
      43. + ^ Wilmshurst, J. M.; Hunt, T. L.; Lipo, C. P.; Anderson, A. J. (2010). "High-precision radiocarbon dating shows recent and rapid initial human colonization of East Polynesia". Proceedings of the National Academy of Sciences. 108 (5): 1815. Bibcode:2011PNAS..108.1815W. doi:10.1073/pnas.1015876108. PMC 3033267. PMID 21187404. + +
      44. +
      45. + ^ McGlone, M.; Wilmshurst, J. M. (1999). "Dating initial Maori environmental impact in New Zealand". Quaternary International. 59: 5–16. Bibcode:1999QuInt..59....5M. doi:10.1016/S1040-6182(98)00067-6. + +
      46. +
      47. + ^ Murray-McIntosh, Rosalind P.; Scrimshaw, Brian J.; Hatfield, Peter J.; Penny, David (1998). "Testing migration patterns and estimating founding population size in Polynesia by using human mtDNA sequences". Proceedings of the National Academy of Sciences of the United States of America. 95 (15): 9047–52. Bibcode:1998PNAS...95.9047M. doi:10.1073/pnas.95.15.9047. PMC 21200. + +
      48. +
      49. + ^ Wilmshurst, J. M.; Anderson, A. J.; Higham, T. F. G.; Worthy, T. H. (2008). "Dating the late prehistoric dispersal of Polynesians to New Zealand using the commensal Pacific rat". Proceedings of the National Academy of Sciences. 105 (22): 7676. Bibcode:2008PNAS..105.7676W. doi:10.1073/pnas.0801507105. PMC 2409139. PMID 18523023. + +
      50. +
      51. + ^ Moodley, Y.; Linz, B.; Yamaoka, Y.; Windsor, H.M.; Breurec, S.; Wu, J.-Y.; Maady, A.; Bernhöft, S.; Thiberge, J.-M.; et al. (2009). "The Peopling of the Pacific from a Bacterial Perspective". Science. 323 (5913): 527–530. Bibcode:2009Sci...323..527M. doi:10.1126/science.1166083. PMC 2827536. PMID 19164753. + +
      52. +
      53. + ^ Ballara, Angela (1998). Iwi: The Dynamics of Māori Tribal Organisation from c. 1769 to c. 1945 (1st ed.). Wellington: Victoria University Press. ISBN 9780864733283. + +
      54. +
      55. + ^ Clark, Ross (1994). "Moriori and Māori: The Linguistic Evidence". In Sutton, Douglas (ed.). The Origins of the First New Zealanders. Auckland: Auckland University Press. pp. 123–135. + +
      56. +
      57. + ^ Davis, Denise (September 2007). "The impact of new arrivals". Te Ara: The Encyclopedia of New Zealand. Retrieved 30 April 2010. + +
      58. +
      59. + ^ Davis, Denise; Solomon, Māui (March 2009). "'Moriori – The impact of new arrivals'". Te Ara: The Encyclopedia of New Zealand. Retrieved 23 March 2011. + +
      60. +
      61. + ^ a b Mein Smith 2005, p. 23. +
      62. +
      63. + ^ Salmond, Anne. Two Worlds: First Meetings Between Maori and Europeans 1642–1772. Auckland: Penguin Books. p. 82. ISBN 0-670-83298-7. + +
      64. +
      65. + ^ King 2003, p. 122. +
      66. +
      67. + ^ Fitzpatrick, John (2004). "Food, warfare and the impact of Atlantic capitalism in Aotearo/New Zealand" (PDF). Australasian Political Studies Association Conference: APSA 2004 Conference Papers. Archived from the original (PDF) on 11 May 2011. + +
      68. +
      69. + ^ Brailsford, Barry (1972). Arrows of Plague. Wellington: Hick Smith and Sons. p. 35. ISBN 0-456-01060-2. + +
      70. +
      71. + ^ Wagstrom, Thor (2005). "Broken Tongues and Foreign Hearts". In Brock, Peggy (ed.). Indigenous Peoples and Religious Change. Boston: Brill Academic Publishers. pp. 71 and 73. ISBN 978-90-04-13899-5. + +
      72. +
      73. + ^ Lange, Raeburn (1999). May the people live: a history of Māori health development 1900–1920. Auckland University Press. p. 18. ISBN 978-1-86940-214-3. + +
      74. +
      75. + ^ "A Nation sub-divided". Australian Heritage. Heritage Australia Publishing. 2011. Archived from the original on 28 February 2015. Retrieved 27 December 2014. + +
      76. +
      77. + ^ a b Rutherford, James (April 2009) [originally published in 1966]. McLintock, Alexander (ed.). Busby, James. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      78. +
      79. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Sir George Gipps. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      80. +
      81. + ^ a b Wilson, John (March 2009). "Government and nation – The origins of nationhood". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 January 2011. + +
      82. +
      83. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Settlement from 1840 to 1852. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      84. +
      85. + ^ Foster, Bernard (April 2009) [originally published in 1966]. McLintock, Alexander (ed.). Akaroa, French Settlement At. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      86. +
      87. + ^ Simpson, K (September 2010). "Hobson, William – Biography". In McLintock, Alexander (ed.). Dictionary of New Zealand Biography. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      88. +
      89. + ^ Phillips, Jock (April 2010). "British immigration and the New Zealand Company". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 January 2011. + +
      90. +
      91. + ^ "Crown colony era – the Governor-General". Ministry for Culture and Heritage. March 2009. Retrieved 7 January 2011. + +
      92. +
      93. + ^ "New Zealand's 19th-century wars – overview". Ministry for Culture and Heritage. April 2009. Retrieved 7 January 2011. + +
      94. +
      95. + ^ a b c d Wilson, John (March 2009). "Government and nation – The constitution". Te Ara: The Encyclopedia of New Zealand. Retrieved 2 February 2011. + See pages 2 and 3. +
      96. +
      97. + ^ Temple, Philip (1980). Wellington Yesterday. John McIndoe. ISBN 0-86868-012-5. + +
      98. +
      99. + ^ "Parliament moves to Wellington". Ministry for Culture and Heritage. January 2017. Retrieved 27 April 2017. + +
      100. +
      101. + ^ a b Wilson, John (March 2009). "History – Liberal to Labour". Te Ara: The Encyclopedia of New Zealand. Retrieved 27 April 2017. + +
      102. +
      103. + ^ Hamer, David. "Seddon, Richard John". Dictionary of New Zealand Biography. Ministry for Culture and Heritage. Retrieved 27 April 2017. + +
      104. +
      105. + ^ Boxall, Peter; Haynes, Peter (1997). "Strategy and Trade Union Effectiveness in a Neo-liberal Environment". British Journal of Industrial Relations. 35 (4): 567–591. doi:10.1111/1467-8543.00069. Archived from the original (PDF) on 11 May 2011. + +
      106. +
      107. + ^ "Proclamation". The London Gazette. No. 28058. 10 September 1907. p. 6149. + +
      108. +
      109. + ^ "Dominion status – Becoming a dominion". Ministry for Culture and Heritage. September 2014. Retrieved 26 April 2017. + +
      110. +
      111. + ^ "War and Society". Ministry for Culture and Heritage. Retrieved 7 January 2011. + +
      112. +
      113. + ^ Easton, Brian (April 2010). "Economic history – Interwar years and the great depression". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 January 2011. + +
      114. +
      115. + ^ Derby, Mark (May 2010). "Strikes and labour disputes – Wars, depression and first Labour government". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 February 2011. + +
      116. +
      117. + ^ Easton, Brian (November 2010). "Economic history – Great boom, 1935–1966". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 February 2011. + +
      118. +
      119. + ^ Keane, Basil (November 2010). "Te Māori i te ohanga – Māori in the economy – Urbanisation". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 January 2011. + +
      120. +
      121. + ^ Royal, Te Ahukaramū (March 2009). "Māori – Urbanisation and renaissance". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 February 2011. + +
      122. +
      123. + ^ Healing the past, building a future: A Guide to Treaty of Waitangi Claims and Negotiations with the Crown (PDF). Office of Treaty Settlements. March 2015. ISBN 978-0-478-32436-5. Retrieved 26 April 2017. + +
      124. +
      125. + ^ Report on the Crown's Foreshore and Seabed Policy (Report). Ministry of Justice. Retrieved 26 April 2017. + +
      126. +
      127. + ^ Barker, Fiona (June 2012). "Debate about the foreshore and seabed". Te Ara: The Encyclopedia of New Zealand. Retrieved 26 April 2017. + +
      128. +
      129. + ^ a b "New Zealand's Constitution". The Governor-General of New Zealand. Retrieved 13 January 2010. + +
      130. +
      131. + ^ a b c "Factsheet – New Zealand – Political Forces". The Economist. The Economist Group. 15 February 2005. Archived from the original on 14 May 2006. Retrieved 4 August 2009. + +
      132. +
      133. + ^ "Royal Titles Act 1974". New Zealand Parliamentary Counsel Office. February 1974. Section 1. Retrieved 8 January 2011. + +
      134. +
      135. + ^ "Constitution Act 1986". New Zealand Parliamentary Counsel Office. 1 January 1987. Section 2.1. Retrieved 15 July 2018. The Sovereign in right of New Zealand is the head of State of New Zealand, and shall be known by the royal style and titles proclaimed from time to time. Cite journal requires |journal= (help) + +
      136. +
      137. + ^ "The Role of the Governor-General". The Governor-General of New Zealand. Retrieved 6 July 2017. + +
      138. +
      139. + ^ Harris, Bruce (2009). "Replacement of the Royal Prerogative in New Zealand". New Zealand Universities Law Review. 23: 285–314. Archived from the original on 18 July 2011. Retrieved 28 August 2016. + +
      140. +
      141. + ^ a b "The Reserve Powers". The Governor-General of New Zealand. Retrieved 8 January 2011. + +
      142. +
      143. + ^ a b c d "Parliament Brief: What is Parliament?". New Zealand Parliament. Retrieved 30 November 2016. + +
      144. +
      145. + ^ McLean, Gavin (February 2015). "Premiers and prime ministers". Te Ara: The Encyclopedia of New Zealand. Retrieved 30 November 2016. + +
      146. +
      147. + ^ Wilson, John (November 2010). "Government and nation – System of government". Te Ara: The Encyclopedia of New Zealand. Retrieved 9 January 2011. + +
      148. +
      149. + ^ "Principles of Cabinet decision making". Cabinet Manual. Department of the Prime Minister and Cabinet. 2008. Retrieved 1 December 2016. + +
      150. +
      151. + ^ "The electoral cycle". Cabinet Manual. Department of the Prime Minister and Cabinet. 2008. Retrieved 30 April 2017. + +
      152. +
      153. + ^ a b "First past the post – the road to MMP". Ministry for Culture and Heritage. September 2009. Retrieved 9 January 2011. + +
      154. +
      155. + ^ "Reviewing electorate numbers and boundaries". Electoral Commission. 8 May 2005. Archived from the original on 9 November 2011. Retrieved 7 July 2018. + +
      156. +
      157. + ^ "Sainte-Laguë allocation formula". Electoral Commission. 4 February 2013. Retrieved 31 May 2014. + +
      158. +
      159. + ^ Paxton, Pamela; Hughes, Melanie M. (2015). Women, Politics, and Power: A Global Perspective. CQ Press. p. 107. ISBN 978-1-48-337701-8. Retrieved 25 July 2017. + +
      160. +
      161. + ^ "Jacinda Ardern sworn in as new Prime Minister". New Zealand Herald. 26 October 2017. Retrieved 26 October 2017. + +
      162. +
      163. + ^ "Female political leaders have been smashing glass ceilings for ages". Stuff.co.nz. Fairfax NZ. 27 October 2017. Retrieved 19 July 2018. + +
      164. +
      165. + ^ "Role of the Chief Justice". Courts of New Zealand. Retrieved 9 June 2018. + +
      166. +
      167. + ^ "Structure of the court system". Courts of New Zealand. Retrieved 9 June 2018. + +
      168. +
      169. + ^ "The Judiciary". Ministry of Justice. Archived from the original on 24 November 2010. Retrieved 9 January 2011. + +
      170. +
      171. + ^ "The Fragile States Index 2016". The Fund for Peace. Archived from the original on 4 February 2017. Retrieved 30 November 2016. + +
      172. +
      173. + ^ "Democracy Index 2017" (PDF). Economist Intelligence Unit. 2018. p. 5. Retrieved 9 December 2018. + +
      174. +
      175. + ^ "Corruption Perceptions Index 2017". Transparency International. 21 February 2018. Retrieved 9 December 2018. + +
      176. +
      177. + ^ "New Zealand". Country Reports on Human Rights Practices for 2017. United States Department of State. Retrieved 9 December 2018. + +
      178. +
      179. + ^ "New Zealand". OECD Better Life Index. 2016. Retrieved 30 November 2016. + +
      180. +
      181. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. External Relations. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      182. +
      183. + ^ "Michael Joseph Savage". Ministry for Culture and Heritage. July 2010. Retrieved 29 January 2011. + +
      184. +
      185. + ^ Patman, Robert (2005). "Globalisation, Sovereignty, and the Transformation of New Zealand Foreign Policy" (PDF). Working Paper 21/05. Centre for Strategic Studies, Victoria University of Wellington. p. 8. Archived from the original (PDF) on 25 September 2007. Retrieved 12 March 2007. + +
      186. +
      187. + ^ "Department Of External Affairs: Security Treaty between Australia, New Zealand and the United States of America". Australian Government. September 1951. Archived from the original on 29 June 2011. Retrieved 11 January 2011. + +
      188. +
      189. + ^ "The Vietnam War". New Zealand History. Ministry for Culture and Heritage. June 2008. Retrieved 11 January 2011. + +
      190. +
      191. + ^ "Sinking the Rainbow Warrior – nuclear-free New Zealand". New Zealand History. Ministry for Culture and Heritage. August 2008. Retrieved 11 January 2011. + +
      192. +
      193. + ^ "Nuclear-free legislation – nuclear-free New Zealand". New Zealand History. Ministry for Culture and Heritage. August 2008. Retrieved 11 January 2011. + +
      194. +
      195. + ^ Lange, David (1990). Nuclear Free: The New Zealand Way. New Zealand: Penguin Books. ISBN 0-14-014519-2. + +
      196. +
      197. + ^ "Australia in brief". Australian Department of Foreign Affairs and Trade. Archived from the original on 22 December 2010. Retrieved 11 January 2011. + +
      198. +
      199. + ^ a b "New Zealand country brief". Australian Department of Foreign Affairs and Trade. Retrieved 11 January 2011. + +
      200. +
      201. + ^ Collett, John (4 September 2013). "Kiwis face hurdles in pursuit of lost funds". Retrieved 4 October 2013. + +
      202. +
      203. + ^ Bertram, Geoff (April 2010). "South Pacific economic relations – Aid, remittances and tourism". Te Ara: The Encyclopedia of New Zealand. Retrieved 11 January 2011. + +
      204. +
      205. + ^ Howes, Stephen (November 2010). "Making migration work: Lessons from New Zealand". Development Policy Centre. Retrieved 23 March 2011. + +
      206. +
      207. + ^ Ayele, Yoseph (28 September 2017). "The Growing Momentum for Global Impact in New Zealand". Edmund Hillary Fellowship. Retrieved 9 July 2019. + +
      208. +
      209. + ^ "Member States of the United Nations". United Nations. Retrieved 11 January 2011. + +
      210. +
      211. + ^ "New Zealand". The Commonwealth. Retrieved 1 December 2016. + +
      212. +
      213. + ^ "Members and partners". Organisation for Economic Co-operation and Development. Retrieved 11 January 2011. + +
      214. +
      215. + ^ "The future of the Five Power Defence Arrangements". The Strategist. 8 November 2012. Retrieved 1 December 2016. + +
      216. +
      217. + ^ "About Us: Role and Responsibilities". New Zealand Defence Force. Retrieved 11 January 2011. + +
      218. +
      219. + ^ Ayson, Robert (2007). "New Zealand Defence and Security Policy,1990–2005". In Alley, Roderic (ed.). New Zealand In World Affairs, Volume IV: 1990–2005. Wellington: Victoria University Press. p. 132. ISBN 978-0-86473-548-5. + +
      220. +
      221. + ^ "The Battle for Crete". New Zealand History. Ministry for Culture and Heritage. May 2010. Retrieved 9 January 2011. + +
      222. +
      223. + ^ "El Alamein – The North African Campaign". New Zealand History. Ministry for Culture and Heritage. May 2009. Retrieved 9 January 2011. + +
      224. +
      225. + ^ Holmes, Richard (September 2010). "World War Two: The Battle of Monte Cassino". Retrieved 9 January 2011. + +
      226. +
      227. + ^ "Gallipoli stirred new sense of national identity says Clark". New Zealand Herald. April 2005. Retrieved 9 January 2011. + +
      228. +
      229. + ^ Prideaux, Bruce (2007). Ryan, Chris (ed.). Battlefield tourism: history, place and interpretation. Elsevier Science. p. 18. ISBN 978-0-08-045362-0. + +
      230. +
      231. + ^ Burke, Arthur. "The Spirit of ANZAC". ANZAC Day Commemoration Committee. Archived from the original on 26 December 2010. Retrieved 11 January 2011. + +
      232. +
      233. + ^ "South African War 1899–1902". Ministry for Culture and Heritage. February 2009. Retrieved 11 January 2011. + +
      234. +
      235. + ^ "New Zealand in the Korean War". New Zealand History. Ministry for Culture and Heritage. Retrieved 1 December 2016. + +
      236. +
      237. + ^ "NZ and the Malayan Emergency". Ministry for Culture and Heritage. August 2010. Retrieved 11 January 2011. + +
      238. +
      239. + ^ "New Zealand Defence Force Overseas Operations". New Zealand Defence Force. January 2008. Archived from the original on 25 January 2008. Retrieved 17 February 2008. + +
      240. +
      241. + ^ a b "New Zealand's Nine Provinces (1853–76)" (PDF). Friends of the Hocken Collections. University of Otago. March 2000. Retrieved 13 January 2011. + +
      242. +
      243. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Provincial Divergencies. An Encyclopaedia of New Zealand. Retrieved 7 January 2011. + +
      244. +
      245. + ^ Swarbrick, Nancy (September 2016). "Public holidays". Te Ara: The Encyclopedia of New Zealand. Retrieved 25 June 2017. + +
      246. +
      247. + ^ "Overview – regional rugby". Ministry for Culture and Heritage. September 2010. Retrieved 13 January 2011. + +
      248. +
      249. + ^ Dollery, Brian; Keogh, Ciaran; Crase, Lin (2007). "Alternatives to Amalgamation in Australian Local Government: Lessons from the New Zealand Experience" (PDF). Sustaining Regions. 6 (1): 50–69. Archived from the original (PDF) on 29 August 2007. + +
      250. +
      251. + ^ a b c Sancton, Andrew (2000). Merger mania: the assault on local government. McGill-Queen's University Press. p. 84. ISBN 0-7735-2163-1. + +
      252. +
      253. + ^ "Subnational population estimates at 30 June 2010 (boundaries at 1 November 2010)". Statistics New Zealand. 26 October 2010. Archived from the original on 10 June 2011. Retrieved 2 April 2011. + +
      254. +
      255. + ^ Smelt & Jui Lin 2009, p. 33. +
      256. +
      257. + ^ a b "Glossary". Department of Internal Affairs. Retrieved 28 August 2016. + +
      258. +
      259. + ^ "Chatham Islands Council Act 1995 No 41". New Zealand Parliamentary Counsel Office. 29 July 1995. Retrieved 8 August 2017. + +
      260. +
      261. + ^ Gimpel, Diane (2011). Monarchies. ABDO Publishing Company. p. 22. ISBN 978-1-617-14792-0. Retrieved 18 November 2016. + +
      262. +
      263. + ^ "System of Government". Government of Niue. Archived from the original on 13 November 2010. Retrieved 13 January 2010. + +
      264. +
      265. + ^ "Government – Structure, Personnel". Government of the Cook Islands. Retrieved 13 January 2010. + +
      266. +
      267. + ^ "Tokelau Government". Government of Tokelau. Retrieved 16 November 2016. + +
      268. +
      269. + ^ "Scott Base". Antarctica New Zealand. Retrieved 13 January 2010. + +
      270. +
      271. + ^ "Citizenship Act 1977 No 61". Zealand Parliamentary Counsel Office. 1 December 1977. Retrieved 26 May 2017. + +
      272. +
      273. + ^ "Check if you're a New Zealand citizen". Department of Internal Affairs. Retrieved 20 January 2015. + +
      274. +
      275. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. The Sea Floor. An Encyclopaedia of New Zealand. Retrieved 13 January 2011. + +
      276. +
      277. + ^ "Hauraki Gulf islands". Auckland City Council. Archived from the original on 25 December 2010. Retrieved 13 January 2011. + +
      278. +
      279. + ^ Hindmarsh (2006). "Discovering D'Urville". Heritage New Zealand. Archived from the original on 11 May 2011. Retrieved 13 January 2011. + +
      280. +
      281. + ^ "Distance tables". Auckland Coastguard. Archived from the original on 23 January 2011. Retrieved 2 March 2011. + +
      282. +
      283. + ^ McKenzie, D. W. (1987). Heinemann New Zealand atlas. Heinemann Publishers. ISBN 0-7900-0187-X. + +
      284. +
      285. + ^ a b c d e f "CIA – The World Factbook". Cia.gov. Retrieved 4 May 2013. + +
      286. +
      287. + ^ "Geography". Statistics New Zealand. 1999. Archived from the original on 22 May 2010. Retrieved 21 December 2009. + +
      288. +
      289. + ^ Offshore Options: Managing Environmental Effects in New Zealand's Exclusive Economic Zone (PDF). Wellington: Ministry for the Environment. 2005. ISBN 0-478-25916-6. Retrieved 23 June 2017. + +
      290. +
      291. + ^ Coates, Glen (2002). The rise and fall of the Southern Alps. Canterbury University Press. p. 15. ISBN 0-908812-93-0. + +
      292. +
      293. + ^ Garden 2005, p. 52. +
      294. +
      295. + ^ Grant, David (March 2009). "Southland places – Fiordland's coast". Te Ara: The Encyclopedia of New Zealand. Retrieved 14 January 2011. + +
      296. +
      297. + ^ "Central North Island volcanoes". Department of Conservation. Archived from the original on 29 December 2010. Retrieved 14 January 2011. + +
      298. +
      299. + ^ Walrond, Carl (March 2009). "Natural environment – Geography and geology". Te Ara: The Encyclopedia of New Zealand. Retrieved 14 January 2010. + +
      300. +
      301. + ^ "Taupo". GNS Science. Archived from the original on 24 March 2011. Retrieved 2 April 2011. + +
      302. +
      303. + ^ a b Lewis, Keith; Nodder, Scott; Carter, Lionel (March 2009). "Sea floor geology – Active plate boundaries". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      304. +
      305. + ^ Wallis, G. P.; Trewick, S. A. (2009). "New Zealand phylogeography: evolution on a small continent". Molecular Ecology. 18 (17): 3548–3580. doi:10.1111/j.1365-294X.2009.04294.x. PMID 19674312. + +
      306. +
      307. + ^ Wright, Dawn; Bloomer, Sherman; MacLeod, Christopher; Taylor, Brian; Goodliffe, Andrew (2000). "Bathymetry of the Tonga Trench and Forearc: A Map Series". Marine Geophysical Researches. 21 (5): 489–512. Bibcode:2000MarGR..21..489W. doi:10.1023/A:1026514914220. + +
      308. +
      309. + ^ "Australasia". New Zealand Oxford Dictionary. Oxford University Press. 2005. doi:10.1093/acref/9780195584516.001.0001. ISBN 9780195584516. + +
      310. +
      311. + ^ Hobbs, Joseph J. (2016). Fundamentals of World Regional Geography. Cengage Learning. p. 367. ISBN 9781305854956. + +
      312. +
      313. + ^ Hillstrom, Kevin; Hillstrom, Laurie Collier (2003). Australia, Oceania, and Antarctica: A Continental Overview of Environmental Issues. 3. ABC-CLIO. p. 25. ISBN 9781576076941. …defined here as the continent nation of Australia, New Zealand, and twenty-two other island countries and territories sprinkled over more than 40 million square kilometres of the South Pacific. + +
      314. +
      315. + ^ a b Mullan, Brett; Tait, Andrew; Thompson, Craig (March 2009). "Climate – New Zealand's climate". Te Ara: The Encyclopedia of New Zealand. Retrieved 15 January 2011. + +
      316. +
      317. + ^ "Summary of New Zealand climate extremes". National Institute of Water and Atmospheric Research. 2004. Retrieved 30 April 2010. + +
      318. +
      319. + ^ Walrond, Carl (March 2009). "Natural environment – Climate". Te Ara: The Encyclopedia of New Zealand. Retrieved 15 January 2011. + +
      320. +
      321. + ^ "Mean monthly rainfall". National Institute of Water and Atmospheric Research. Archived from the original (XLS) on 3 May 2011. Retrieved 4 February 2011. + +
      322. +
      323. + ^ "Mean monthly sunshine hours". National Institute of Water and Atmospheric Research. Archived from the original (XLS) on 15 October 2008. Retrieved 4 February 2011. + +
      324. +
      325. + ^ "New Zealand climate and weather". Tourism New Zealand. Retrieved 13 November 2016. + +
      326. +
      327. + ^ "Climate data and activities". National Institute of Water and Atmospheric Research. Retrieved 11 February 2016. + +
      328. +
      329. + ^ Cooper, R.; Millener, P. (1993). "The New Zealand biota: Historical background and new research". Trends in Ecology & Evolution. 8 (12): 429. doi:10.1016/0169-5347(93)90004-9. + +
      330. +
      331. + ^ Trewick SA, Morgan-Richards M. 2014. New Zealand Wild Life. Penguin, New Zealand. + ISBN 9780143568896 +
      332. +
      333. + ^ Lindsey, Terence; Morris, Rod (2000). Collins Field Guide to New Zealand Wildlife. HarperCollins (New Zealand) Limited. p. 14. ISBN 978-1-86950-300-0. + +
      334. +
      335. + ^ a b "Frequently asked questions about New Zealand plants". New Zealand Plant Conservation Network. May 2010. Retrieved 15 January 2011. + +
      336. +
      337. + ^ De Lange, Peter James; Sawyer, John William David & Rolfe, Jeremy (2006). New Zealand indigenous vascular plant checklist. New Zealand Plant Conservation Network. ISBN 0-473-11306-6. + +
      338. +
      339. + ^ Wassilieff, Maggy (March 2009). "Lichens – Lichens in New Zealand". Te Ara: The Encyclopedia of New Zealand. Retrieved 16 January 2011. + +
      340. +
      341. + ^ McLintock, Alexander, ed. (April 2010) [originally published in 1966]. Mixed Broadleaf Podocarp and Kauri Forest. An Encyclopaedia of New Zealand. Retrieved 15 January 2011. + +
      342. +
      343. + ^ Mark, Alan (March 2009). "Grasslands – Tussock grasslands". Te Ara: The Encyclopedia of New Zealand. Retrieved 17 January 2010. + +
      344. +
      345. + ^ "Commentary on Forest Policy in the Asia-Pacific Region (A Review for Indonesia, Malaysia, New Zealand, Papua New Guinea, Philippines, Thailand and Western Samoa)". Forestry Department. 1997. Retrieved 4 February 2011. + +
      346. +
      347. + ^ McGlone, M.S. (1989). "The Polynesian settlement of New Zealand in relation to environmental and biotic changes" (PDF). New Zealand Journal of Ecology. 12(S): 115–129. Archived from the original (PDF) on 17 July 2014. + +
      348. +
      349. + ^ Taylor, R. and Smith, I. (1997). The state of New Zealand’s environment 1997. Ministry for the Environment, Wellington. +
      350. +
      351. + ^ "New Zealand ecology: Flightless birds". TerraNature. Retrieved 17 January 2011. + +
      352. +
      353. + ^ a b Holdaway, Richard (March 2009). "Extinctions – New Zealand extinctions since human arrival". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      354. +
      355. + ^ Kirby, Alex (January 2005). "Huge eagles 'dominated NZ skies'". BBC News. Retrieved 4 February 2011. + +
      356. +
      357. + ^ "Reptiles and frogs". Department of Conservation. Archived from the original on 29 January 2015. Retrieved 25 June 2017. + +
      358. +
      359. + ^ Pollard, Simon (September 2007). "Spiders and other arachnids". Te Ara: The Encyclopedia of New Zealand. Retrieved 25 June 2017. + +
      360. +
      361. + ^ "Wētā". Department of Conservation. Retrieved 25 June 2017. + +
      362. +
      363. + ^ Ryan, Paddy (March 2009). "Snails and slugs – Flax snails, giant snails and veined slugs". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      364. +
      365. + ^ Herrera-Flores, Jorge A.; Stubbs, Thomas L.; Benton, Michael J.; Ruta, Marcello (May 2017). "Macroevolutionary patterns in Rhynchocephalia: is the tuatara (Sphenodon punctatus) a living fossil?". Palaeontology. 60 (3): 319–328. doi:10.1111/pala.12284. + +
      366. +
      367. + ^ "Tiny Bones Rewrite Textbooks, first New Zealand land mammal fossil". University of New South Wales. 31 May 2007. Archived from the original on 31 May 2007. + +
      368. +
      369. + ^ Worthy, Trevor H.; Tennyson, Alan J. D.; Archer, Michael; Musser, Anne M.; Hand, Suzanne J.; Jones, Craig; Douglas, Barry J.; McNamara, James A.; Beck, Robin M. D. (2006). "Miocene mammal reveals a Mesozoic ghost lineage on insular New Zealand, southwest Pacific". Proceedings of the National Academy of Sciences of the United States of America. 103 (51): 19419–23. Bibcode:2006PNAS..10319419W. doi:10.1073/pnas.0605684103. PMC 1697831. PMID 17159151. + +
      370. +
      371. + ^ "Marine Mammals". Department of Conservation. Archived from the original on 8 March 2011. Retrieved 17 January 2011. + +
      372. +
      373. + ^ "Sea and shore birds". Department of Conservation. Retrieved 7 March 2011. + +
      374. +
      375. + ^ "Penguins". Department of Conservation. Retrieved 7 March 2011. + +
      376. +
      377. + ^ Jones, Carl (2002). "Reptiles and Amphibians". In Perrow, Martin; Davy, Anthony (eds.). Handbook of ecological restoration: Principles of Restoration. 2. Cambridge University Press. p. 362. ISBN 0-521-79128-6. + +
      378. +
      379. + ^ Towns, D.; Ballantine, W. (1993). "Conservation and restoration of New Zealand Island ecosystems". Trends in Ecology & Evolution. 8 (12): 452. doi:10.1016/0169-5347(93)90009-E. + +
      380. +
      381. + ^ Rauzon, Mark (2008). "Island restoration: Exploring the past, anticipating the future" (PDF). Marine Ornithology. 35: 97–107. + +
      382. +
      383. + ^ Diamond, Jared (1990). Towns, D; Daugherty, C; Atkinson, I (eds.). New Zealand as an archipelago: An international perspective (PDF). Wellington: Conservation Sciences Publication No. 2. Department of Conservation. pp. 3–8. + +
      384. +
      385. + ^ World Economic Outlook. International Monetary Fund. April 2018. p. 63. ISBN 978-1-48434-971-7. Retrieved 21 June 2018. + +
      386. +
      387. + ^ "Rankings on Economic Freedom". The Heritage Foundation. 2016. Retrieved 30 November 2016. + +
      388. +
      389. + ^ "Currencies of the territories listed in the BS exchange rate lists". Bank of Slovenia. Retrieved 22 January 2011. + +
      390. +
      391. + ^ a b c McLintock, Alexander, ed. (November 2009) [originally published in 1966]. Historical evolution and trade patterns. An Encyclopaedia of New Zealand. Retrieved 10 February 2011. + +
      392. +
      393. + ^ Stringleman, Hugh; Peden, Robert (October 2009). "Sheep farming – Growth of the frozen meat trade, 1882–2001". Te Ara: The Encyclopedia of New Zealand. Retrieved 6 May 2010. + +
      394. +
      395. + ^ Baker, John (February 2010) [1966]. McLintock, Alexander (ed.). Some Indicators of Comparative Living Standards. An Encyclopaedia of New Zealand. Retrieved 30 April 2010. + PDF Table +
      396. +
      397. + ^ Wilson, John (March 2009). "History – The later 20th century". Te Ara: The Encyclopedia of New Zealand. Retrieved 2 February 2011. + +
      398. +
      399. + ^ Nixon, Chris; Yeabsley, John (April 2010). "Overseas trade policy – Difficult times – the 1970s and early 1980s". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      400. +
      401. + ^ Evans, N. "Up From Down Under: After a Century of Socialism, Australia and New Zealand are Cutting Back Government and Freeing Their Economies". National Review. 46 (16): 47–51. + +
      402. +
      403. + ^ Trade, Food Security, and Human Rights: The Rules for International Trade in Agricultural Products and the Evolving World Food Crisis. Routledge. 2016. p. 125. ISBN 9781317008521. + +
      404. +
      405. + ^ Wayne Arnold (2 August 2007). "Surviving Without Subsidies". The New York Times. Retrieved 11 August 2015. ... ever since a liberal but free-market government swept to power in 1984 and essentially canceled handouts to farmers ... They went cold turkey and in the process it was very rough on their farming economy + +
      406. +
      407. + ^ Easton, Brian (November 2010). "Economic history – Government and market liberalisation". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 February 2011. + +
      408. +
      409. + ^ Hazledine, Tim (1998). Taking New Zealand Seriously: The Economics of Decency (PDF). HarperCollins Publishers. ISBN 1-86950-283-3. Archived from the original (PDF) on 10 May 2011. + +
      410. +
      411. + ^ "NZ tops Travellers' Choice Awards". Stuff Travel. May 2008. Retrieved 30 April 2010. + +
      412. +
      413. + ^ a b c "Unemployment: the Social Report 2016 – Te pūrongo oranga tangata". Ministry of Social Development. Retrieved 18 August 2017. + +
      414. +
      415. + ^ "New Zealand Takes a Pause in Cutting Rates". The New York Times. 10 June 2009. Retrieved 30 April 2010. + +
      416. +
      417. + ^ "New Zealand's slump longest ever". BBC News. 26 June 2009. Retrieved 30 April 2010. + +
      418. +
      419. + ^ Bascand, Geoff (February 2011). "Household Labour Force Survey: December 2010 quarter – Media Release". Statistics New Zealand. Archived from the original on 29 April 2011. Retrieved 4 February 2011. + +
      420. +
      421. + ^ Davenport, Sally (2004). "Panic and panacea: brain drain and science and technology human capital policy". Research Policy. 33 (4): 617–630. doi:10.1016/j.respol.2004.01.006. + +
      422. +
      423. + ^ O'Hare, Sean (September 2010). "New Zealand brain-drain worst in world". The Daily Telegraph. United Kingdom. + +
      424. +
      425. + ^ Collins, Simon (March 2005). "Quarter of NZ's brightest are gone". New Zealand Herald. + +
      426. +
      427. + ^ Winkelmann, Rainer (2000). "The labour market performance of European immigrants in New Zealand in the 1980s and 1990s". The International Migration Review. The Center for Migration Studies of New York. 33 (1): 33–58. doi:10.2307/2676011. JSTOR 2676011. + Journal subscription required +
      428. +
      429. + ^ Bain 2006, p. 44. +
      430. +
      431. + ^ "GII 2016 Report" (PDF). Global Innovation Index. Retrieved 21 June 2018. + +
      432. +
      433. + ^ Groser, Tim (March 2009). "Speech to ASEAN-Australia-New Zealand Free Trade Agreement Seminars". New Zealand Government. Retrieved 30 January 2011. + +
      434. +
      435. + ^ "Improving Access to Markets:Agriculture". New Zealand Ministry of Foreign Affairs and Trade. Retrieved 22 January 2011. + +
      436. +
      437. + ^ "Standard International Trade Classification R4 – Exports (Annual-Jun)". Statistics New Zealand. April 2015. Retrieved 3 April 2015. + +
      438. +
      439. + ^ a b c "Goods and services trade by country: Year ended June 2018 – corrected". Statistics New Zealand. Retrieved 17 February 2019. + +
      440. +
      441. + ^ "China and New Zealand sign free trade deal". The New York Times. April 2008. + +
      442. +
      443. + ^ a b "Key Tourism Statistics" (PDF). Ministry of Business, Innovation and Employment. 26 April 2017. Retrieved 26 April 2017. + +
      444. +
      445. + ^ Easton, Brian (March 2009). "Economy – Agricultural production". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      446. +
      447. + ^ Stringleman, Hugh; Peden, Robert (March 2009). "Sheep farming – Changes from the 20th century". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      448. +
      449. + ^ Stringleman, Hugh; Scrimgeour, Frank (November 2009). "Dairying and dairy products – Dairying in the 2000s". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      450. +
      451. + ^ Stringleman, Hugh; Scrimgeour, Frank (March 2009). "Dairying and dairy products – Dairy exports". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      452. +
      453. + ^ Stringleman, Hugh; Scrimgeour, Frank (March 2009). "Dairying and dairy products – Manufacturing and marketing in the 2000s". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      454. +
      455. + ^ Dalley, Bronwyn (March 2009). "Wine – The wine boom, 1980s and beyond". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      456. +
      457. + ^ "Wine in New Zealand". The Economist. 27 March 2008. Retrieved 29 April 2017. + +
      458. +
      459. + ^ "Agricultural and forestry exports from New Zealand: Primary sector export values for the year ending June 2010". Ministry of Agriculture and Forestry. 14 January 2011. Archived from the original on 10 May 2011. Retrieved 8 April 2011. + +
      460. +
      461. + ^ a b Energy in New Zealand 2016 (PDF) (Report). Ministry of Business, Innovation and Employment. September 2016. p. 47. ISSN 2324-5913. Archived from the original (PDF) on 3 May 2017. + +
      462. +
      463. + ^ "Appendix 1: Technical information about drinking water supply in the eight local authorities". Office of the Auditor-General. Retrieved 2 September 2016. + +
      464. +
      465. + ^ "Water supply". Greater Wellington Regional Council. Retrieved 2 September 2016. + +
      466. +
      467. + ^ "State highway frequently asked questions". NZ Transport Agency. Retrieved 28 April 2017. + +
      468. +
      469. + ^ Humphris, Adrian (April 2010). "Public transport – Passenger trends". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      470. +
      471. + ^ Atkinson, Neill (November 2010). "Railways – Rail transformed". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      472. +
      473. + ^ "About Metlink". Retrieved 27 December 2016. + +
      474. +
      475. + ^ Atkinson, Neill (April 2010). "Railways – Freight transport". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      476. +
      477. + ^ "International Visitors" (PDF). Ministry of Economic Development. June 2009. Retrieved 30 January 2011. + +
      478. +
      479. + ^ "10. Airports". Infrastructure Stocktake: Infrastructure Audit. Ministry of Economic Development. December 2005. Archived from the original on 22 May 2010. Retrieved 30 January 2011. + +
      480. +
      481. + ^ a b Wilson, A. C. (March 2010). "Telecommunications - Telecom". Te Ara: The Encyclopedia of New Zealand. Retrieved 11 August 2017. + +
      482. +
      483. + ^ "Telecom separation". Ministry of Business, Innovation and Employment. 14 September 2015. Retrieved 11 August 2017. + +
      484. +
      485. + ^ "Broadband and mobile programmes - Ministry of Business, Innovation & Employment". www.mbie.govt.nz. + +
      486. +
      487. + ^ "2017 Global ICT Development Index". International Telecommunication Union (ITU). 2018. Retrieved 18 September 2018. + +
      488. +
      489. + ^ "2013 Census usually resident population counts". Statistics New Zealand. 14 October 2013. Retrieved 20 September 2018. + +
      490. +
      491. + ^ "National population projections: 2016(base)–2068" (Press release). Statistics New Zealand. 18 October 2016. Retrieved 20 October 2018. + +
      492. +
      493. + ^ "Subnational population estimates at 30 June 2009". Statistics New Zealand. 30 June 2007. Retrieved 30 April 2010. + +
      494. +
      495. + ^ "Quality of Living Ranking 2016". London: Mercer. 23 February 2016. Retrieved 28 April 2017. + +
      496. +
      497. + ^ "NZ life expectancy among world's best". Stuff.co.nz. Fairfax NZ. Retrieved 6 July 2014. + +
      498. +
      499. + ^ a b Department of Economic and Social Affairs Population Division (2009). "World Population Prospects" (PDF). 2008 revision. United Nations. Retrieved 29 August 2009. Cite journal requires |journal= (help) + +
      500. +
      501. + ^ "World Factbook EUROPE : NEW ZEALAND", The World Factbook, 12 July 2018 + +
      502. +
      503. + ^ "New Zealand mortality statistics: 1950 to 2010" (PDF). Ministry of Health of New Zealand. 2 March 2011. Retrieved 16 November 2016. + +
      504. +
      505. + ^ "Health expenditure and financing". stats.oecd.org. OECD. 2016. Retrieved 8 December 2017. + +
      506. +
      507. + ^ "Subnational Population Estimates: At 30 June 2018 (provisional)". Statistics New Zealand. 23 October 2018. Retrieved 23 October 2018. + For urban areas, "Subnational population estimates (UA, AU), by age and sex, at 30 June 1996, 2001, 2006-18 (2017 boundaries)". Statistics New Zealand. 23 October 2018. Retrieved 23 October 2018. + +
      508. +
      509. + ^ "2013 Census QuickStats about culture and identity – Ethnic groups in New Zealand". Statistics New Zealand. Retrieved 29 August 2014. + +
      510. +
      511. + ^ Pool, Ian (May 2011). "Population change - Key population trends". Te Ara: The Encyclopedia of New Zealand. Archived from the original on 18 August 2017. Retrieved 18 August 2017. + +
      512. +
      513. + ^ Dalby, Simon (September 1993). "The 'Kiwi disease': geopolitical discourse in Aotearoa/New Zealand and the South Pacific". Political Geography. 12 (5): 437–456. doi:10.1016/0962-6298(93)90012-V. + +
      514. +
      515. + ^ Callister, Paul (2004). "Seeking an Ethnic Identity: Is "New Zealander" a Valid Ethnic Category?" (PDF). New Zealand Population Review. 30 (1&2): 5–22. + +
      516. +
      517. + ^ Bain 2006, p. 31. +
      518. +
      519. + ^ "Draft Report of a Review of the Official Ethnicity Statistical Standard: Proposals to Address the 'New Zealander' Response Issue" (PDF). Statistics New Zealand. April 2009. Retrieved 18 January 2011. + +
      520. +
      521. + ^ Ranford, Jodie. "'Pakeha', Its Origin and Meaning". Māori News. Retrieved 20 February 2008. Originally the Pakeha were the early European settlers, however, today ‘Pakeha’ is used to describe any peoples of non-Maori or non-Polynesian heritage. Pakeha is not an ethnicity but rather a way to differentiate between the historical origins of our settlers, the Polynesians and the Europeans, the Maori and the other + +
      522. +
      523. + ^ Socidad Peruana de Medicina Intensiva (SOPEMI) (2000). Trends in international migration: continuous reporting system on migration. Organisation for Economic Co-operation and Development. pp. 276–278. + +
      524. +
      525. + ^ Walrond, Carl (21 September 2007). "Dalmatians". Te Ara: The Encyclopedia of New Zealand. Retrieved 30 April 2010. + +
      526. +
      527. + ^ "Peoples". Te Ara: The Encyclopedia of New Zealand. 2005. Retrieved 2 June 2017. + +
      528. +
      529. + ^ a b Phillips, Jock (11 August 2015). "History of immigration". Te Ara: The Encyclopedia of New Zealand. Retrieved 2 June 2017. + +
      530. +
      531. + ^ Brawley, Sean (1993). "'No White Policy in NZ': Fact and Fiction in New Zealand's Asian Immigration Record, 1946-1978" (PDF). New Zealand Journal of History. 27 (1): 33–36. Retrieved 2 June 2017. + +
      532. +
      533. + ^ "International Migration Outlook – New Zealand 2009/10" (PDF). New Zealand Department of Labour. 2010. p. 2. ISSN 1179-5085. Archived from the original (PDF) on 11 May 2011. Retrieved 16 April 2011. + +
      534. +
      535. + ^ "2013 Census QuickStats about culture and identity – Birthplace and people born overseas". Statistics New Zealand. Retrieved 29 August 2014. + +
      536. +
      537. + ^ Butcher, Andrew; McGrath, Terry (2004). "International Students in New Zealand: Needs and Responses" (PDF). International Education Journal. 5 (4). + +
      538. +
      539. + ^ 2013 Census QuickStats, Statistics New Zealand, 2013, ISBN 978-0-478-40864-5 + +
      540. +
      541. + ^ a b c "2013 Census QuickStats about culture and identity – Languages spoken". Statistics New Zealand. Retrieved 8 September 2016. + +
      542. +
      543. + ^ Hay, Maclagan & Gordon 2008, p. 14. +
      544. +
      545. + ^ * Bauer, Laurie; Warren, Paul; Bardsley, Dianne; Kennedy, Marianna; Major, George (2007), "New Zealand English", Journal of the International Phonetic Association, 37 (1): 97–102, doi:10.1017/S0025100306002830 + +
      546. +
      547. + ^ a b Phillips, Jock (March 2009). "The New Zealanders – Bicultural New Zealand". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      548. +
      549. + ^ Squires, Nick (May 2005). "British influence ebbs as New Zealand takes to talking Māori". The Daily Telegraph. Retrieved 3 May 2017. + +
      550. +
      551. + ^ "Waitangi Tribunal claim – Māori Language Week". Ministry for Culture and Heritage. July 2010. Retrieved 19 January 2011. + +
      552. +
      553. + ^ "Ngā puna kōrero: Where Māori speak te reo – infographic". Statistics New Zealand. Retrieved 8 September 2016. + +
      554. +
      555. + ^ Drinnan, John (8 July 2016). "'Maori' will remain in the name Maori Television". New Zealand Herald. Retrieved 28 August 2016. According to 2015 figures supplied by Maori TV, its two channels broadcast an average of 72 per cent Maori language content - 59 per cent on the main channel and 99 per cent on te reo. + +
      556. +
      557. + ^ "Ngāi Tahu Claims Settlement Act 1998". New Zealand Parliamentary Counsel Office. 20 May 2014 [1 October 1998]. Retrieved 10 March 2019. + +
      558. +
      559. + ^ New Zealand Sign Language Act 2006 No 18 (as at 30 June 2008), Public Act. New Zealand Parliamentary Counsel Office. Retrieved 29 November 2011. +
      560. +
      561. + ^ Zuckerman, Phil (2006). Martin, Michael (ed.). The Cambridge Companion to Atheism (PDF). Cambridge University Press. pp. 47–66. ISBN 978-0-521-84270-9. Retrieved 8 August 2017. + +
      562. +
      563. + ^ Walrond, Carl (May 2012). "Atheism and secularism – Who is secular?". Te Ara: The Encyclopedia of New Zealand. Retrieved 8 August 2017. + +
      564. +
      565. + ^ a b "2013 Census QuickStats about culture and identity – Religious affiliation". Statistics New Zealand. 15 April 2014. Retrieved 25 July 2015. + +
      566. +
      567. + ^ a b c "2013 Census QuickStats about culture and identity – tables". Statistics New Zealand. 15 April 2014. Retrieved 14 April 2018. + Excel download +
      568. +
      569. + ^ Kaa, Hirini (May 2011). "Māori and Christian denominations". Te Ara: The Encyclopedia of New Zealand. Retrieved 20 April 2017. + +
      570. +
      571. + ^ Morris, Paul (May 2011). "Diverse religions". Te Ara: The Encyclopedia of New Zealand. Retrieved 20 April 2017. + +
      572. +
      573. + ^ a b Dench, Olivia (July 2010). "Education Statistics of New Zealand: 2009". Education Counts. Retrieved 19 January 2011. + +
      574. +
      575. + ^ "Education Act 1989 No 80". New Zealand Parliamentary Counsel Office. 1989. Section 3. Retrieved 5 January 2013. + +
      576. +
      577. + ^ "Education Act 1989 No 80 (as at 01 February 2011), Public Act. Part 14: Establishment and disestablishment of tertiary institutions, Section 62: Establishment of institutions". Education Act 1989 No 80. New Zealand Parliamentary Counsel Office. 1 February 2011. Retrieved 15 August 2011. + +
      578. +
      579. + ^ "Studying in New Zealand: Tertiary education". New Zealand Qualifications Authority. Retrieved 15 August 2011. + +
      580. +
      581. + ^ "Educational attainment of the population". Education Counts. 2006. Archived from the original (xls) on 15 October 2008. Retrieved 21 February 2008. + +
      582. +
      583. + ^ "What Students Know and Can Do: Student Performance in Reading, Mathematics and Science 2010" (PDF). + OECD. Retrieved 21 July 2012. +
      584. +
      585. + ^ Kennedy 2007, p. 398. +
      586. +
      587. + ^ Hearn, Terry (March 2009). "English – Importance and influence". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      588. +
      589. + ^ "Conclusions – British and Irish immigration". Ministry for Culture and Heritage. March 2007. Retrieved 21 January 2011. + +
      590. +
      591. + ^ Stenhouse, John (November 2010). "Religion and society – Māori religion". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      592. +
      593. + ^ "Māori Social Structures". Ministry of Justice. March 2001. Retrieved 21 January 2011. + +
      594. +
      595. + ^ "Thousands turn out for Pasifika Festival". Radio New Zealand. 25 March 2017. Retrieved 18 August 2017. + +
      596. +
      597. + ^ Kennedy 2007, p. 400. +
      598. +
      599. + ^ Kennedy 2007, p. 399. +
      600. +
      601. + ^ Phillips, Jock (March 2009). "The New Zealanders – Post-war New Zealanders". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      602. +
      603. + ^ Phillips, Jock (March 2009). "The New Zealanders – Ordinary blokes and extraordinary sheilas". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      604. +
      605. + ^ Phillips, Jock (March 2009). "Rural mythologies – The cult of the pioneer". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      606. +
      607. + ^ Barker, Fiona (June 2012). "New Zealand identity – Culture and arts". Te Ara: The Encyclopedia of New Zealand. Retrieved 7 December 2016. + +
      608. +
      609. + ^ a b Wilson, John (September 2016). "Nation and government – Nationhood and identity". Te Ara: The Encyclopedia of New Zealand. Retrieved 3 December 2016. + +
      610. +
      611. + ^ a b Swarbrick, Nancy (June 2010). "Creative life – Visual arts and crafts". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      612. +
      613. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Elements of Carving. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      614. +
      615. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Surface Patterns. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      616. +
      617. + ^ McKay, Bill (2004). "Māori architecture: transforming western notions of architecture". Fabrications. 14 (1&2): 1–12. doi:10.1080/10331867.2004.10525189. Archived from the original on 13 May 2011. + +
      618. +
      619. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Painted Designs. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      620. +
      621. + ^ McLintock, Alexander, ed. (2009) [1966]. Tattooing. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      622. +
      623. + ^ a b "Beginnings – history of NZ painting". Ministry for Culture and Heritage. December 2010. Retrieved 17 February 2011. + +
      624. +
      625. + ^ "A new New Zealand art – history of NZ painting". Ministry for Culture and Heritage. November 2010. Retrieved 16 February 2011. + +
      626. +
      627. + ^ "Contemporary Maori art". Ministry for Culture and Heritage. November 2010. Retrieved 16 February 2011. + +
      628. +
      629. + ^ Rauer, Julie. "Paradise Lost: Contemporary Pacific Art At The Asia Society". Asia Society and Museum. Retrieved 17 February 2011. + +
      630. +
      631. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Textile Designs. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      632. +
      633. + ^ Keane, Basil (March 2009). "Pounamu – jade or greenstone – Implements and adornment". Te Ara: The Encyclopedia of New Zealand. Retrieved 17 February 2011. + +
      634. +
      635. + ^ Wilson, John (March 2009). "Society – Food, drink and dress". Te Ara: The Encyclopedia of New Zealand. Retrieved 17 February 2011. + +
      636. +
      637. + ^ Swarbrick, Nancy (June 2010). "Creative life – Design and fashion". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      638. +
      639. + ^ a b "Fashion in New Zealand – New Zealand's fashion industry". The Economist. 28 February 2008. Retrieved 6 August 2009. + +
      640. +
      641. + ^ Swarbrick, Nancy (June 2010). "Creative life – Writing and publishing". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2011. + +
      642. +
      643. + ^ "The making of New Zealand literature". Ministry for Culture and Heritage. November 2010. Retrieved 22 January 2011. + +
      644. +
      645. + ^ "New directions in the 1930s – New Zealand literature". Ministry for Culture and Heritage. August 2008. Retrieved 12 February 2011. + +
      646. +
      647. + ^ "The war and beyond – New Zealand literature". Ministry for Culture and Heritage. November 2007. Retrieved 12 February 2011. + +
      648. +
      649. + ^ "28 cities join the UNESCO Creative Cities Network". UNESCO. December 2014. Retrieved 7 March 2015. + +
      650. +
      651. + ^ a b Swarbrick, Nancy (June 2010). "Creative life – Music". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      652. +
      653. + ^ McLintock, Alexander, ed. (April 2009) [originally published in 1966]. Maori Music. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      654. +
      655. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Musical Instruments. An Encyclopaedia of New Zealand. Retrieved 16 February 2011. + +
      656. +
      657. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Instruments Used for Non-musical Purposes. An Encyclopaedia of New Zealand. Retrieved 16 February 2011. + +
      658. +
      659. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Music: General History. An Encyclopaedia of New Zealand. Retrieved 15 February 2011. + +
      660. +
      661. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Music: Brass Bands. An Encyclopaedia of New Zealand. Retrieved 14 April 2011. + +
      662. +
      663. + ^ McLintock, Alexander, ed. (April 2009) [1966]. Music: Pipe Bands. An Encyclopaedia of New Zealand. Retrieved 14 April 2011. + +
      664. +
      665. + ^ Swarbrick, Nancy (June 2010). "Creative life – Performing arts". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      666. +
      667. + ^ "History – celebrating our music since 1965". Recording Industry Association of New Zealand. 2008. Archived from the original on 14 September 2011. Retrieved 23 January 2012. + +
      668. +
      669. + ^ "About RIANZ – Introduction". Recording Industry Association of New Zealand. Archived from the original on 21 December 2011. Retrieved 23 January 2012. + +
      670. +
      671. + ^ Downes, Siobhan (1 January 2017). "World famous in New Zealand: Hobbiton Movie Set". Stuff Travel. Retrieved 6 July 2017. + +
      672. +
      673. + ^ Brian, Pauling (October 2014). "Radio – The early years, 1921 to 1932". Te Ara: The Encyclopedia of New Zealand. Retrieved 6 July 2017. + +
      674. +
      675. + ^ "New Zealand's first official TV broadcast". Ministry for Culture and Heritage. December 2016. Retrieved 6 July 2017. + +
      676. +
      677. + ^ a b Swarbrick, Nancy (June 2010). "Creative life – Film and broadcasting". Te Ara: The Encyclopedia of New Zealand. Retrieved 21 January 2011. + +
      678. +
      679. + ^ Horrocks, Roger. "A History of Television in New Zealand". NZ On Screen. Retrieved 13 September 2017. + +
      680. +
      681. + ^ "Top 10 Highest Grossing New Zealand Movies Ever". Flicks.co.nz. May 2016. Retrieved 11 August 2017. + +
      682. +
      683. + ^ Cieply, Michael; Rose, Jeremy (October 2010). "New Zealand Bends and 'Hobbit' Stays". The New York Times. Retrieved 11 August 2017. + +
      684. +
      685. + ^ "Production Guide: Locations". Film New Zealand. Archived from the original on 7 November 2010. Retrieved 21 January 2011. + +
      686. +
      687. + ^ Myllylahti, Merja (December 2016). JMAD New Zealand Media Ownership Report 2016 (PDF) (Report). Auckland University of Technology. pp. 4–29. Archived from the original (PDF) on 21 May 2017. Retrieved 11 August 2017. + +
      688. +
      689. + ^ "Scores and Status Data 1980-2015". Freedom of the Press 2015. Freedom House. Retrieved 23 November 2016. + +
      690. +
      691. + ^ Hearn, Terry (March 2009). "English – Popular culture". Te Ara: The Encyclopedia of New Zealand. Retrieved 22 January 2012. + +
      692. +
      693. + ^ "Sport, Fitness and Leisure". New Zealand Official Yearbook. Statistics New Zealand. 2000. Archived from the original on 7 June 2011. Retrieved 21 July 2008. Traditionally New Zealanders have excelled in rugby union, which is regarded as the national sport, and track and field athletics. + +
      694. +
      695. + ^ a b Phillips, Jock (February 2011). "Sports and leisure – Organised sports". Te Ara: The Encyclopedia of New Zealand. Retrieved 23 March 2011. + +
      696. +
      697. + ^ a b "More and more students wear school sports colours". New Zealand Secondary School Sports Council. Retrieved 30 March 2015. + +
      698. +
      699. + ^ Crawford, Scott (January 1999). "Rugby and the Forging of National Identity". In Nauright, John (ed.). Sport, Power And Society In New Zealand: Historical And Contemporary Perspectives (PDF). ASSH Studies In Sports History. Archived from the original (PDF) on 19 January 2012. Retrieved 22 January 2011. + +
      700. +
      701. + ^ "Rugby, racing and beer". Ministry for Culture and Heritage. August 2010. Retrieved 22 January 2011. + +
      702. +
      703. + ^ Derby, Mark (December 2010). "Māori–Pākehā relations – Sports and race". Te Ara: The Encyclopedia of New Zealand. Retrieved 4 February 2011. + +
      704. +
      705. + ^ Bain 2006, p. 69. +
      706. +
      707. + ^ Langton, Graham (1996). A history of mountain climbing in New Zealand to 1953 (Thesis). Christchurch: University of Canterbury. p. 28. Retrieved 12 August 2017. + +
      708. +
      709. + ^ "World mourns Sir Edmund Hillary". The Age. Melbourne. 11 January 2008. + +
      710. +
      711. + ^ "Sport and Recreation Participation Levels" (PDF). Sport and Recreation New Zealand. 2009. Archived from the original (PDF) on 15 January 2015. Retrieved 27 November 2016. + +
      712. +
      713. + ^ Barclay-Kerr, Hoturoa (September 2013). "Waka ama – outrigger canoeing". Te Ara: The Encyclopedia of New Zealand. Retrieved 12 August 2017. + +
      714. +
      715. + ^ "NZ's first Olympic century". Ministry for Culture and Heritage. August 2016. Retrieved 27 April 2017. + +
      716. +
      717. + ^ "London 2012 Olympic Games: Medal strike rate – Final count (revised)". Statistics New Zealand. 14 August 2012. Retrieved 4 December 2013. + +
      718. +
      719. + ^ "Rio 2016 Olympic Games: Medals per capita". Statistics New Zealand. 30 August 2016. Retrieved 27 April 2017. + +
      720. +
      721. + ^ Kerr, James (14 November 2013). "The All Blacks guide to being successful (off the field)". The Daily Telegraph. London. Retrieved 4 December 2013. + +
      722. +
      723. + ^ Fordyce, Tom (23 October 2011). "2011 Rugby World Cup final: New Zealand 8-7 France". BBC Sport. Retrieved 4 December 2013. + +
      724. +
      725. + ^ a b "New Zealand Cuisine". New Zealand Tourism Guide. January 2016. Retrieved 4 January 2016. + +
      726. +
      727. + ^ Petrie, Hazel (November 2008). "Kai Pākehā – introduced foods". Te Ara: The Encyclopedia of New Zealand. Retrieved 27 June 2017. + +
      728. +
      729. + ^ Whaanga, Mere (June 2006). "Mātaitai – shellfish gathering". Te Ara: The Encyclopedia of New Zealand. Retrieved 27 June 2017. + +
      730. +
      731. + ^ "Story: Shellfish". Te Ara: The Encyclopedia of New Zealand. Retrieved 29 August 2016. + +
      732. +
      733. + ^ Burton, David (September 2013). "Cooking – Cooking methods". Te Ara: The Encyclopedia of New Zealand. Retrieved 11 December 2016. + +
      734. +
      735. + ^ Royal, Charles; Kaka-Scott, Jenny (September 2013). "Māori foods – kai Māori". Te Ara: The Encyclopedia of New Zealand. Retrieved 1 September 2016. + +
      736. +
      +
      +

      + References +

      +
      +
        +
      • + Alley, Roderic (2008). New Zealand in World Affairs IV 1990–2005. New Zealand: Victoria University Press. ISBN 978-0-864-73548-5. + +
      • +
      • + Bain, Carolyn (2006). New Zealand. Lonely Planet. ISBN 1-74104-535-5. + +
      • +
      • + Garden, Donald (2005). Stoll, Mark (ed.). Australia, New Zealand, and the Pacific: An Environmental History. Nature and Human Societies. ABC-CLIO/Greenwood. ISBN 978-1-57607-868-6. + +
      • +
      • + Hay, Jennifer; Maclagan, Margaret; Gordon, Elizabeth (2008). Dialects of English: New Zealand English. Edinburgh University Press. ISBN 978-0-7486-2529-1. + +
      • +
      • + Kennedy, Jeffrey (2007). "Leadership and Culture in New Zealand". In Chhokar, Jagdeep; Brodbeck, Felix; House, Robert (eds.). Culture and Leadership Across the World: The GLOBE Book of In-Depth Studies of 25 Societies. United States: Psychology Press. ISBN 978-0-8058-5997-3. + +
      • +
      • + King, Michael (2003). The Penguin History of New Zealand. New Zealand: Penguin Books. ISBN 978-0-14-301867-4. + +
      • +
      • + Mein Smith, Philippa (2005). A Concise History of New Zealand. Australia: Cambridge University Press. ISBN 0-521-54228-6. + +
      • +
      • + Smelt, Roselynn; Jui Lin, Yong (2009). New Zealand. Cultures of the World (2nd ed.). New York: Marshall Cavendish. ISBN 978-0-7614-3415-3. + +
      • +
      +
      +

      + Further reading +

      + +
      + +
      +

      + External links +

      + +
      +
      + Government +
      +
      + +
      +
      + Travel +
      +
      + +
      +
      + General Information +
      +
      + + + + + + +
      +
      + + +
      +
      +
      +
      +
      +
      +
      +

      + Navigation menu +

      +
      + +
      + + +
      +
      + + + +
      +
      +
      + + + + + + + +
      +
      + + + + + + diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected-images.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected-images.json new file mode 100644 index 000000000..caa1f9b4b --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected-images.json @@ -0,0 +1,53 @@ +[ + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/28a0aaa74b2267a48312e19321211cd9e3a39228", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/6ca00b61ff0e264e6c1e5adc9a00c0d2751feecf", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/7daff47fa58cdfd29dc333def748ff5fa4c923e3", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/d9415702ab196cc26f5df37af2d90e07318e93df", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/291d260bf69b764e75818669ab27870d58771e1f", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/8aa270391d183478251283d2c4b2c72ac4563352", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/5541bfa07743be995242c892c344395e672d6fa2", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/459de45e76bace9d04a80d2e8efc2abbbc246047", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/6425c6e94fa47976601cb44d7564b5d04dcfbfef", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/9a50080b735975d8001c9552ac2134b49ad534c0", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/997ea0350c18735926412de88420ac9ca989f50c", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/54bf0331204e30cba9ec7f695dfea97e6745a7c2", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/92efef0e89bdc77f6a848764195ef5b9d9bfcc6a", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/00ccf11c16396b6ddd4f2254f7132cd8bb2c57ee", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/3f0efab2d7c3a4b4b7caf14cc0705dadd13195a9", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/47136aad860d145f75f3eed3022df827cee94d7a", + "http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/1\/1c\/Wiki_letter_w_cropped.svg\/44px-Wiki_letter_w_cropped.svg.png", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/4fa8265c5f6d4fc3b7cda6a06558c7d4d9aec855", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/0f1862750b96d01100244370b3fca45f01923ce5", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/251bf4ebbe3b0d119e0a7d19f8fd134c4f072971", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/021893240ff7fa3148b6649b0ba4d88cd207b5f0", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/a28a8250ab35ad60228bb0376eb4b7024f027815", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/a0179c3a7aebe194ccd9a19ba02b972500f88a7a", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/b6cf8185ca7a0687bf959bb65b16db6cf1714ca2", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/d303a1ebcac8547489b170be5d0dd7d8e04e548e", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/992c8ea49fdd26b491180036c5a4d879fec77442", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/46eedb181c0bdae46e8c1526161b03d0ea97b4b4", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/ddeac51c423f6dbefc5f63e483d9aee96e6fa342", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/db65cce3a8fa33e5b7b96badd756c8573aa866c0", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/add78d8608ad86e54951b8c8bd6c8d8416533d20", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/4ea1ea9ac61e6e1e84ac39130f78143c18865719", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/3b7d749931e5f709bcbc0a446638d3b6b8ed0c6c", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/fa91daf9145f27bb95746fd2a37537342d587b77", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/1934e7eadd31fbf6f7d6bcf9c0e9bec934ce8976", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/a1240df64c3010e0be6eae865fdfcfe6f77bf5eb", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/43cc392bdcfbb134dd66d9b469847f6370e29d9d", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/3ef97bb04ce4ab682bcc84cf1059f8da235b483e", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/f4ac665be4943ce769e33109e9f64abcf1e98050", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/0919d2e50fe1008af261f8301f243c002c328dbf", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/f8ed067bb4bc06662d6bdf6210d450779a529ce5", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/6ad9b0047f8437f7b012041d7b2fcd190a5a9ec2", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/b431248ab2f121914608bbd1c2376715cecda9c8", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/d4ee4832d06e8560510d81237d0650c897d476e9", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/b1d54d3c850d35f99329591e3b57cef98d17237f", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/86a67b81c2de995bd608d5b2df50cd8cd7d92455", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/82c24522483ceaf1d54224b69af4244b60c3ac08", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/87f9e315fd7e2ba406057a97300593c4802b53e4", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/486623019ef451e0582b874018e0249a46e0f996", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/18fbf88c578fc9f75d4610ebd18ab55f4f2842ce", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/200db82bfdbc81cd227cb3470aa826d6f11a7653", + "https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/957584ae6a35f9edf293cb486d7436fb5b75e803" +] \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected-metadata.json b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected-metadata.json new file mode 100644 index 000000000..27df15632 --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected-metadata.json @@ -0,0 +1,8 @@ +{ + "Author": "Contributors to Wikimedia projects", + "Direction": "ltr", + "Excerpt": "In mathematics, a Hermitian matrix (or self-adjoint matrix) is a complex square matrix that is equal to its own conjugate transpose\u2014that is, the element in the i-th row and j-th column is equal to the complex conjugate of the element in the j-th row and i-th column, for all indices i and j:", + "Image": null, + "Title": "Hermitian matrix", + "SiteName": "Wikimedia Foundation, Inc." +} \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected.html new file mode 100644 index 000000000..ff7c62cbf --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/expected.html @@ -0,0 +1,354 @@ +
      + + +

      + In mathematics, a Hermitian matrix (or self-adjoint matrix) is a complex square matrix that is equal to its own conjugate transpose—that is, the element in the i-th row and j-th column is equal to the complex conjugate of the element in the j-th row and i-th column, for all indices i and j: +

      +

      + +

      +

      + or in matrix form: +

      +
      +
      + . +
      +
      +

      + Hermitian matrices can be understood as the complex extension of real symmetric matrices. +

      +

      + If the conjugate transpose of a matrix is denoted by , then the Hermitian property can be written concisely as +

      +

      + +

      +

      + Hermitian matrices are named after Charles Hermite, who demonstrated in 1855 that matrices of this form share a property with real symmetric matrices of always having real eigenvalues. Other, equivalent notations in common use are , although note that in quantum mechanics, typically means the complex conjugate only, and not the conjugate transpose. +

      + +

      + Alternative characterizations[edit] +

      +

      + Hermitian matrices can be characterized in a number of equivalent ways, some of which are listed below: +

      +

      + Equality with the adjoint[edit] +

      +

      + A square matrix is Hermitian if and only if it is equal to its adjoint, that is, it satisfies +

      +
      +

      +

      for any pair of vectors , where denotes the inner product operation. +

      + This is also the way that the more general concept of self-adjoint operator is defined. +

      +

      + Reality of quadratic forms[edit] +

      +

      + A square matrix is Hermitian if and only if it is such that +

      +
      +

      +

      +

      + Spectral properties[edit] +

      +

      + A square matrix is Hermitian if and only if it is unitarily diagonalizable with real eigenvalues. +

      +

      + Applications[edit] +

      +

      + Hermitian matrices are fundamental to the quantum theory of matrix mechanics created by Werner Heisenberg, Max Born, and Pascual Jordan in 1925. +

      +

      + Examples[edit] +

      +

      + In this section, the conjugate transpose of matrix is denoted as , the transpose of matrix is denoted as and conjugate of matrix is denoted as . +

      +

      + See the following example: +

      +
      +
      + +
      +
      +

      + The diagonal elements must be real, as they must be their own complex conjugate. +

      +

      + Well-known families of Pauli matrices, Gell-Mann matrices and their generalizations are Hermitian. In theoretical physics such Hermitian matrices are often multiplied by imaginary coefficients,[1][2] which results in skew-Hermitian matrices (see below). +

      +

      + Here, we offer another useful Hermitian matrix using an abstract example. If a square matrix equals the multiplication of a matrix and its conjugate transpose, that is, , then is a Hermitian positive semi-definite matrix. Furthermore, if is row full-rank, then is positive definite. +

      +

      + Properties[edit] +

      + + + + + + + +
      +

      [icon] +

      +
      +

      + This section needs expansion with: Proof of the properties requested. You can help by adding to it. (February 2018) +

      +
      + +
      +
      + Proof: By definition of the Hermitian matrix +
      +
      + +
      +
      +
      +
      + so for i = j the above follows. +
      +
      + Only the main diagonal entries are necessarily real; Hermitian matrices can have arbitrary complex-valued entries in their off-diagonal elements, as long as diagonally-opposite entries are complex conjugates. +
      +
      + +
      +
      + Proof: by definition. Thus Hij = Hji (matrix symmetry) if and only if (Hij is real). +
      +
      + +
      +
      + Proof: A = AH, so AAH = AA = AHA. +
      +
      + + +
      +
      + Proof: as claimed. +
      +
      + +
      +
      + Proof: If , then , so as claimed. +
      +
      + +
      +
      + Proof: Note that Thus if and only if . +
      +
      + Thus An is Hermitian if A is Hermitian and n is an integer. +
      +
      + + +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + together with the set of matrices of the form +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + and the matrices +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + where denotes the complex number , called the imaginary unit. +
      +
      + +
      +
      +
      +
      + +
      +
      +
      +
      + where are the eigenvalues on the diagonal of the diagonal matrix . +
      +
      + +
      +
      + Proof: +
      +
      + Therefore if . +
      +
      + (Alternatively, the determinant is the product of the matrix's eigenvalues, and as mentioned before, the eigenvalues of a Hermitian matrix are real.) +
      +
      +

      + Decomposition into Hermitian and skew-Hermitian[edit] +

      +

      + Additional facts related to Hermitian matrices include: +

      + + + +
      +
      +
      +
      + +
      +
      +
      +
      +

      + Rayleigh quotient[edit] +

      + +

      + In mathematics, for a given complex Hermitian matrix M and nonzero vector x, the Rayleigh quotient[4] , is defined as:[3]:p. 234[5] +

      +
      +
      + . +
      +
      +

      + For real matrices and vectors, the condition of being Hermitian reduces to that of being symmetric, and the conjugate transpose to the usual transpose . Note that for any non-zero real scalar . Also, recall that a Hermitian (or real symmetric) matrix has real eigenvalues. +

      +

      + It can be shown[citation needed] that, for a given matrix, the Rayleigh quotient reaches its minimum value (the smallest eigenvalue of M) when is (the corresponding eigenvector). Similarly, and . +

      +

      + The Rayleigh quotient is used in the min-max theorem to get exact values of all eigenvalues. It is also used in eigenvalue algorithms to obtain an eigenvalue approximation from an eigenvector approximation. Specifically, this is the basis for Rayleigh quotient iteration. +

      +

      + The range of the Rayleigh quotient (for matrix that is not necessarily Hermitian) is called a numerical range (or spectrum in functional analysis). When the matrix is Hermitian, the numerical range is equal to the spectral norm. Still in functional analysis, is known as the spectral radius. In the context of C*-algebras or algebraic quantum mechanics, the function that to M associates the Rayleigh quotient R(M, x) for a fixed x and M varying through the algebra would be referred to as "vector state" of the algebra. +

      +

      + See also[edit] +

      + +

      + References[edit] +

      + +

      + External links[edit] +

      + + + +
      \ No newline at end of file diff --git a/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/source.html b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/source.html new file mode 100644 index 000000000..c22e2b4ee --- /dev/null +++ b/plugins/af_readability/vendor/fivefilters/readability.php/test/test-pages/wikipedia-3/source.html @@ -0,0 +1,3757 @@ + + + + + + Hermitian matrix - Wikipedia + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      + +
      + +
      +
      +

      + Hermitian matrix +

      +
      +
      + From Wikipedia, the free encyclopedia +
      +
      +
      Jump to navigation Jump to search +
      +
      + + +

      + In mathematics, a Hermitian matrix (or self-adjoint matrix) is a complex square matrix that is equal to its own conjugate transpose—that is, the element in the i-th row and j-th column is equal to the complex conjugate of the element in the j-th row and i-th column, for all indices i and j: +

      +
      +

      + +

      +
      +

      + or in matrix form: +

      +
      +
      + . +
      +
      +

      + Hermitian matrices can be understood as the complex extension of real symmetric matrices. +

      +

      + If the conjugate transpose of a matrix is denoted by , then the Hermitian property can be written concisely as +

      +
      +

      + +

      +
      +

      + Hermitian matrices are named after Charles Hermite, who demonstrated in 1855 that matrices of this form share a property with real symmetric matrices of always having real eigenvalues. Other, equivalent notations in common use are , although note that in quantum mechanics, typically means the complex conjugate only, and not the conjugate transpose. +

      + +

      + Alternative characterizations[edit] +

      +

      + Hermitian matrices can be characterized in a number of equivalent ways, some of which are listed below: +

      +

      + Equality with the adjoint[edit] +

      +

      + A square matrix is Hermitian if and only if it is equal to its adjoint, that is, it satisfies +

      +
      + +
      for any pair of vectors , where denotes the inner product operation. +

      + This is also the way that the more general concept of self-adjoint operator is defined. +

      +

      + Reality of quadratic forms[edit] +

      +

      + A square matrix is Hermitian if and only if it is such that +

      +
      + +
      +

      + Spectral properties[edit] +

      +

      + A square matrix is Hermitian if and only if it is unitarily diagonalizable with real eigenvalues. +

      +

      + Applications[edit] +

      +

      + Hermitian matrices are fundamental to the quantum theory of matrix mechanics created by Werner Heisenberg, Max Born, and Pascual Jordan in 1925. +

      +

      + Examples[edit] +

      +

      + In this section, the conjugate transpose of matrix is denoted as , the transpose of matrix is denoted as and conjugate of matrix is denoted as . +

      +

      + See the following example: +

      +
      +
      + +
      +
      +

      + The diagonal elements must be real, as they must be their own complex conjugate. +

      +

      + Well-known families of Pauli matrices, Gell-Mann matrices and their generalizations are Hermitian. In theoretical physics such Hermitian matrices are often multiplied by imaginary coefficients,[1][2] which results in skew-Hermitian matrices (see below). +

      +

      + Here, we offer another useful Hermitian matrix using an abstract example. If a square matrix equals the multiplication of a matrix and its conjugate transpose, that is, , then is a Hermitian positive semi-definite matrix. Furthermore, if is row full-rank, then is positive definite. +

      +

      + Properties[edit] +

      + + + + + + + + +
        +
      • The entries on the main diagonal (top left to bottom right) of any Hermitian matrix are real. +
      • +
      +
      +
      + Proof: By definition of the Hermitian matrix +
      +
      + +
      +
      +
      +
      + so for i = j the above follows. +
      +
      + Only the main diagonal entries are necessarily real; Hermitian matrices can have arbitrary complex-valued entries in their off-diagonal elements, as long as diagonally-opposite entries are complex conjugates. +
      +
      +
        +
      • A matrix that has only real entries is Hermitian if and only if it is symmetric. A real and symmetric matrix is simply a special case of a Hermitian matrix. +
      • +
      +
      +
      + Proof: by definition. Thus Hij = Hji (matrix symmetry) if and only if (Hij is real). +
      +
      +
        +
      • Every Hermitian matrix is a normal matrix. That is to say, AAH = AHA. +
      • +
      +
      +
      + Proof: A = AH, so AAH = AA = AHA. +
      +
      +
        +
      • The finite-dimensional spectral theorem says that any Hermitian matrix can be diagonalized by a unitary matrix, and that the resulting diagonal matrix has only real entries. This implies that all eigenvalues of a Hermitian matrix A with dimension n are real, and that A has n linearly independent eigenvectors. Moreover, a Hermitian matrix has orthogonal eigenvectors for distinct eigenvalues. Even if there are degenerate eigenvalues, it is always possible to find an orthogonal basis of n consisting of n eigenvectors of A. +
      • +
      +
        +
      • The sum of any two Hermitian matrices is Hermitian. +
      • +
      +
      +
      + Proof: as claimed. +
      +
      +
        +
      • The inverse of an invertible Hermitian matrix is Hermitian as well. +
      • +
      +
      +
      + Proof: If , then , so as claimed. +
      +
      +
        +
      • The product of two Hermitian matrices A and B is Hermitian if and only if AB = BA. +
      • +
      +
      +
      + Proof: Note that Thus if and only if . +
      +
      + Thus An is Hermitian if A is Hermitian and n is an integer. +
      +
      +
        +
      • For an arbitrary complex valued vector v the product is real because of . This is especially important in quantum physics where Hermitian matrices are operators that measure properties of a system e.g. total spin which have to be real. +
      • +
      +
        +
      • The Hermitian complex n-by-n matrices do not form a vector space over the complex numbers, , since the identity matrix In is Hermitian, but iIn is not. However the complex Hermitian matrices do form a vector space over the real numbers . In the 2n2-dimensional vector space of complex n × n matrices over , the complex Hermitian matrices form a subspace of dimension n2. If Ejk denotes the n-by-n matrix with a 1 in the j,k position and zeros elsewhere, a basis (orthonormal w.r.t. the Frobenius inner product) can be described as follows: +
      • +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + together with the set of matrices of the form +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + and the matrices +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      + where denotes the complex number , called the imaginary unit. +
      +
      +
        +
      • If n orthonormal eigenvectors of a Hermitian matrix are chosen and written as the columns of the matrix U, then one eigendecomposition of A is where and therefore +
      • +
      +
      +
      +
      +
      + +
      +
      +
      +
      + where are the eigenvalues on the diagonal of the diagonal matrix . +
      +
      +
        +
      • The determinant of a Hermitian matrix is real: +
      • +
      +
      +
      + Proof: +
      +
      + Therefore if . +
      +
      + (Alternatively, the determinant is the product of the matrix's eigenvalues, and as mentioned before, the eigenvalues of a Hermitian matrix are real.) +
      +
      +

      + Decomposition into Hermitian and skew-Hermitian[edit] +

      +

      + Additional facts related to Hermitian matrices include: +

      +
        +
      • The sum of a square matrix and its conjugate transpose is Hermitian. +
      • +
      +
        +
      • The difference of a square matrix and its conjugate transpose is skew-Hermitian (also called antihermitian). This implies that the commutator of two Hermitian matrices is skew-Hermitian. +
      • +
      +
        +
      • An arbitrary square matrix C can be written as the sum of a Hermitian matrix A and a skew-Hermitian matrix B. This is known as the Toeplitz decomposition of C.[3]:p. 7 +
      • +
      +
      +
      +
      +
      + +
      +
      +
      +
      +

      + Rayleigh quotient[edit] +

      + +

      + In mathematics, for a given complex Hermitian matrix M and nonzero vector x, the Rayleigh quotient[4] , is defined as:[3]:p. 234[5] +

      +
      +
      + . +
      +
      +

      + For real matrices and vectors, the condition of being Hermitian reduces to that of being symmetric, and the conjugate transpose to the usual transpose . Note that for any non-zero real scalar . Also, recall that a Hermitian (or real symmetric) matrix has real eigenvalues. +

      +

      + It can be shown[citation needed] that, for a given matrix, the Rayleigh quotient reaches its minimum value (the smallest eigenvalue of M) when is (the corresponding eigenvector). Similarly, and . +

      +

      + The Rayleigh quotient is used in the min-max theorem to get exact values of all eigenvalues. It is also used in eigenvalue algorithms to obtain an eigenvalue approximation from an eigenvector approximation. Specifically, this is the basis for Rayleigh quotient iteration. +

      +

      + The range of the Rayleigh quotient (for matrix that is not necessarily Hermitian) is called a numerical range (or spectrum in functional analysis). When the matrix is Hermitian, the numerical range is equal to the spectral norm. Still in functional analysis, is known as the spectral radius. In the context of C*-algebras or algebraic quantum mechanics, the function that to M associates the Rayleigh quotient R(M, x) for a fixed x and M varying through the algebra would be referred to as "vector state" of the algebra. +

      +

      + See also[edit] +

      + +

      + References[edit] +

      +
      +
      +
        +
      1. + ^ Frankel, Theodore (2004). The Geometry of Physics: an introduction. Cambridge University Press. p. 652. ISBN 0-521-53927-7. +
      2. +
      3. + ^ Physics 125 Course Notes at California Institute of Technology +
      4. +
      5. + ^ a b Horn, Roger A.; Johnson, Charles R. (2013). Matrix Analysis, second edition. Cambridge University Press. ISBN 9780521839402. + +
      6. +
      7. + ^ Also known as the Rayleigh–Ritz ratio; named after Walther Ritz and Lord Rayleigh. +
      8. +
      9. + ^ Parlet B. N. The symmetric eigenvalue problem, SIAM, Classics in Applied Mathematics,1998 +
      10. +
      +
      +
      +

      + External links[edit] +

      + + + +
      +
      + + +
      +
      +
      +
      +
      +
      +
      +

      + Navigation menu +

      +
      + +
      + + +
      +
      + + + +
      +
      +
      + + + + + + +
      +
      + + + + + + diff --git a/plugins/af_readability/vendor/masterminds/html5/.gitattributes b/plugins/af_readability/vendor/masterminds/html5/.gitattributes new file mode 100644 index 000000000..3d291a027 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/.gitattributes @@ -0,0 +1,8 @@ +.gitattributes export-ignore +.gitignore export-ignore +.php_cs.dist export-ignore +.scrutinizer.yml export-ignore +.travis.yml export-ignore +example.php export-ignore +phpunit.xml.dist export-ignore +/test export-ignore diff --git a/plugins/af_readability/vendor/masterminds/html5/.gitignore b/plugins/af_readability/vendor/masterminds/html5/.gitignore new file mode 100644 index 000000000..1fa9e5861 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/.gitignore @@ -0,0 +1,5 @@ +vendor/ +scratch.php +composer.lock +build/ +.php_cs.cache diff --git a/plugins/af_readability/vendor/masterminds/html5/.php_cs.dist b/plugins/af_readability/vendor/masterminds/html5/.php_cs.dist new file mode 100644 index 000000000..d5e49183d --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/.php_cs.dist @@ -0,0 +1,14 @@ +in(__DIR__) +; + +return PhpCsFixer\Config::create() + ->setRules(array( + '@Symfony' => true, + 'concat_space' => array('spacing' => 'one'), + 'phpdoc_annotation_without_dot' => false, + )) + ->setFinder($finder) +; diff --git a/plugins/af_readability/vendor/masterminds/html5/.scrutinizer.yml b/plugins/af_readability/vendor/masterminds/html5/.scrutinizer.yml new file mode 100644 index 000000000..dcdd2047c --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/.scrutinizer.yml @@ -0,0 +1,41 @@ +tools: + php_mess_detector: true + php_analyzer: + config: + parameter_reference_check: { enabled: false } + checkstyle: { enabled: false, no_trailing_whitespace: true, naming: { enabled: true, local_variable: '^[a-z][a-zA-Z0-9]*$', abstract_class_name: ^Abstract|Factory$, utility_class_name: 'Utils?$', constant_name: '^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$', property_name: '^[a-z][a-zA-Z0-9]*$', method_name: '^(?:[a-z]|__)[a-zA-Z0-9]*$', parameter_name: '^[a-z][a-zA-Z0-9]*$', interface_name: '^[A-Z][a-zA-Z0-9]*Interface$', type_name: '^[A-Z][a-zA-Z0-9]*$', exception_name: '^[A-Z][a-zA-Z0-9]*Exception$', isser_method_name: '^(?:is|has|should|may|supports)' } } + unreachable_code: { enabled: false } + check_access_control: { enabled: false } + typo_checks: { enabled: false } + check_variables: { enabled: false } + check_calls: { enabled: true, too_many_arguments: true, missing_argument: true, argument_type_checks: lenient } + suspicious_code: { enabled: false, overriding_parameter: false, overriding_closure_use: false, parameter_closure_use_conflict: false, parameter_multiple_times: false, non_existent_class_in_instanceof_check: false, non_existent_class_in_catch_clause: false, assignment_of_null_return: false, non_commented_switch_fallthrough: false, non_commented_empty_catch_block: false, overriding_private_members: false, use_statement_alias_conflict: false, precedence_in_condition_assignment: false } + dead_assignments: { enabled: false } + verify_php_doc_comments: { enabled: false, parameters: false, return: false, suggest_more_specific_types: false, ask_for_return_if_not_inferrable: false, ask_for_param_type_annotation: false } + loops_must_use_braces: { enabled: false } + check_usage_context: { enabled: true, foreach: { value_as_reference: true, traversable: true } } + simplify_boolean_return: { enabled: false } + phpunit_checks: { enabled: false } + reflection_checks: { enabled: false } + precedence_checks: { enabled: true, assignment_in_condition: true, comparison_of_bit_result: true } + basic_semantic_checks: { enabled: false } + unused_code: { enabled: false } + deprecation_checks: { enabled: false } + useless_function_calls: { enabled: false } + metrics_lack_of_cohesion_methods: { enabled: false } + metrics_coupling: { enabled: true, stable_code: { namespace_prefixes: { }, classes: { } } } + doctrine_parameter_binding: { enabled: false } + doctrine_entity_manager_injection: { enabled: false } + symfony_request_injection: { enabled: false } + doc_comment_fixes: { enabled: false } + reflection_fixes: { enabled: false } + use_statement_fixes: { enabled: true, remove_unused: true, preserve_multiple: false, preserve_blanklines: false, order_alphabetically: false } + php_code_sniffer: true + sensiolabs_security_checker: true + php_cpd: true + php_loc: true + php_pdepend: true + external_code_coverage: true +filter: + paths: + - src/* diff --git a/plugins/af_readability/vendor/masterminds/html5/.travis.yml b/plugins/af_readability/vendor/masterminds/html5/.travis.yml new file mode 100644 index 000000000..44661b1d2 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/.travis.yml @@ -0,0 +1,47 @@ +language: php +dist: trusty +sudo: false + +matrix: + include: + - php: 5.3 + dist: precise + env: COMPOSER_FLAGS="--prefer-lowest" + - php: 5.4 + - php: 5.5 + - php: 5.6 + env: SCRUTINIZER=1 PHPUNIT_FLAGS="--coverage-clover=coverage.xml" + - php: 7.0 + env: COMPOSER_FLAGS="--prefer-lowest" + - php: 7.1 + env: CS_FIXER=1 + - php: 7.2 + - php: 7.3 + env: BENCHMARK=1 + - php: 7.4 + - php: 8.0 + dist: bionic + fast_finish: true + +cache: + directories: + - $HOME/.composer/cache + +before_script: + - if [[ SCRUTINIZER != '1' ]]; then phpenv config-rm xdebug.ini || true; fi + - composer self-update + - if [[ ${TRAVIS_PHP_VERSION:0:1} == "8" ]]; then composer config platform.php 7.4; fi + - composer update $COMPOSER_FLAGS --prefer-dist + +script: + - stty cols 120 + - if [ "$CS_FIXER" == 1 ]; then wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v2.13.1/php-cs-fixer.phar && php php-cs-fixer.phar fix --dry-run --diff; fi + - mkdir -p build/logs + - ./vendor/bin/phpunit $PHPUNIT_FLAGS + +after_script: + - if [ "$SCRUTINIZER" == 1 ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover coverage.xml; fi + - if [ "$BENCHMARK" == 1 ]; then php test/benchmark/run.php 10; fi + +notifications: + irc: "irc.freenode.net#masterminds" diff --git a/plugins/af_readability/vendor/masterminds/html5/example.php b/plugins/af_readability/vendor/masterminds/html5/example.php new file mode 100644 index 000000000..e4e1f22f9 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/example.php @@ -0,0 +1,32 @@ + + + TEST + + + + +
      +

      Hello World

      This is a test of the HTML5 parser.

      +
      + & Nobody nowhere. +
      + TEST + + © + +HERE; + +$html5 = new HTML5(); +$dom = $html5->loadHTML($html); + +echo "Converting to HTML 5\n"; + +$html5->save($dom, fopen('php://stdin', 'w')); diff --git a/plugins/af_readability/vendor/masterminds/html5/phpunit.xml.dist b/plugins/af_readability/vendor/masterminds/html5/phpunit.xml.dist new file mode 100644 index 000000000..8e7750d5b --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/phpunit.xml.dist @@ -0,0 +1,8 @@ + + + + + test/HTML5/ + + + diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/ElementsTest.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/ElementsTest.php new file mode 100644 index 000000000..08b5ee425 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/ElementsTest.php @@ -0,0 +1,485 @@ +html5Elements as $element) { + $this->assertTrue(Elements::isHtml5Element($element), 'html5 element test failed on: ' . $element); + + $this->assertTrue(Elements::isHtml5Element(strtoupper($element)), 'html5 element test failed on: ' . strtoupper($element)); + } + + $nonhtml5 = array( + 'foo', + 'bar', + 'baz', + ); + foreach ($nonhtml5 as $element) { + $this->assertFalse(Elements::isHtml5Element($element), 'html5 element test failed on: ' . $element); + + $this->assertFalse(Elements::isHtml5Element(strtoupper($element)), 'html5 element test failed on: ' . strtoupper($element)); + } + } + + public function testIsMathMLElement() + { + foreach ($this->mathmlElements as $element) { + $this->assertTrue(Elements::isMathMLElement($element), 'MathML element test failed on: ' . $element); + + // MathML is case sensitive so these should all fail. + $this->assertFalse(Elements::isMathMLElement(strtoupper($element)), 'MathML element test failed on: ' . strtoupper($element)); + } + + $nonMathML = array( + 'foo', + 'bar', + 'baz', + ); + foreach ($nonMathML as $element) { + $this->assertFalse(Elements::isMathMLElement($element), 'MathML element test failed on: ' . $element); + } + } + + public function testIsSvgElement() + { + foreach ($this->svgElements as $element) { + $this->assertTrue(Elements::isSvgElement($element), 'SVG element test failed on: ' . $element); + + // SVG is case sensitive so these should all fail. + $this->assertFalse(Elements::isSvgElement(strtoupper($element)), 'SVG element test failed on: ' . strtoupper($element)); + } + + $nonSVG = array( + 'foo', + 'bar', + 'baz', + ); + foreach ($nonSVG as $element) { + $this->assertFalse(Elements::isSvgElement($element), 'SVG element test failed on: ' . $element); + } + } + + public function testIsElement() + { + foreach ($this->html5Elements as $element) { + $this->assertTrue(Elements::isElement($element), 'html5 element test failed on: ' . $element); + + $this->assertTrue(Elements::isElement(strtoupper($element)), 'html5 element test failed on: ' . strtoupper($element)); + } + + foreach ($this->mathmlElements as $element) { + $this->assertTrue(Elements::isElement($element), 'MathML element test failed on: ' . $element); + + // MathML is case sensitive so these should all fail. + $this->assertFalse(Elements::isElement(strtoupper($element)), 'MathML element test failed on: ' . strtoupper($element)); + } + + foreach ($this->svgElements as $element) { + $this->assertTrue(Elements::isElement($element), 'SVG element test failed on: ' . $element); + + // SVG is case sensitive so these should all fail. But, there is duplication + // html5 and SVG. Since html5 is case insensitive we need to make sure + // it's not a html5 element first. + if (!in_array($element, $this->html5Elements)) { + $this->assertFalse(Elements::isElement(strtoupper($element)), 'SVG element test failed on: ' . strtoupper($element)); + } + } + + $nonhtml5 = array( + 'foo', + 'bar', + 'baz', + ); + foreach ($nonhtml5 as $element) { + $this->assertFalse(Elements::isElement($element), 'html5 element test failed on: ' . $element); + + $this->assertFalse(Elements::isElement(strtoupper($element)), 'html5 element test failed on: ' . strtoupper($element)); + } + } + + public function testElement() + { + foreach ($this->html5Elements as $element) { + $this->assertGreaterThan(0, Elements::element($element)); + } + $nonhtml5 = array( + 'foo', + 'bar', + 'baz', + ); + foreach ($nonhtml5 as $element) { + $this->assertEquals(0, Elements::element($element)); + } + } + + public function testIsA() + { + $this->assertTrue(Elements::isA('script', Elements::KNOWN_ELEMENT)); + $this->assertFalse(Elements::isA('scriptypoo', Elements::KNOWN_ELEMENT)); + $this->assertTrue(Elements::isA('script', Elements::TEXT_RAW)); + $this->assertFalse(Elements::isA('script', Elements::TEXT_RCDATA)); + + $voidElements = array( + 'area', + 'base', + 'basefont', + 'bgsound', + 'br', + 'col', + 'command', + 'embed', + 'frame', + 'hr', + 'img', + ); + + foreach ($voidElements as $element) { + $this->assertTrue(Elements::isA($element, Elements::VOID_TAG), 'Void element test failed on: ' . $element); + } + + $nonVoid = array( + 'span', + 'a', + 'div', + ); + foreach ($nonVoid as $tag) { + $this->assertFalse(Elements::isA($tag, Elements::VOID_TAG), 'Void element test failed on: ' . $tag); + } + + $blockTags = array( + 'address', + 'article', + 'aside', + 'blockquote', + 'canvas', + 'dd', + 'div', + 'dl', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'header', + 'hgroup', + 'hr', + 'noscript', + 'ol', + 'output', + 'p', + 'pre', + 'section', + 'table', + 'tfoot', + 'ul', + 'video', + ); + + foreach ($blockTags as $tag) { + $this->assertTrue(Elements::isA($tag, Elements::BLOCK_TAG), 'Block tag test failed on: ' . $tag); + } + + $nonBlockTags = array( + 'span', + 'img', + 'label', + ); + foreach ($nonBlockTags as $tag) { + $this->assertFalse(Elements::isA($tag, Elements::BLOCK_TAG), 'Block tag test failed on: ' . $tag); + } + } + + public function testNormalizeSvgElement() + { + $tests = array( + 'foo' => 'foo', + 'altglyph' => 'altGlyph', + 'BAR' => 'bar', + 'fespecularlighting' => 'feSpecularLighting', + 'bAz' => 'baz', + 'foreignobject' => 'foreignObject', + ); + + foreach ($tests as $input => $expected) { + $this->assertEquals($expected, Elements::normalizeSvgElement($input)); + } + } + + public function testNormalizeSvgAttribute() + { + $tests = array( + 'foo' => 'foo', + 'attributename' => 'attributeName', + 'BAR' => 'bar', + 'limitingconeangle' => 'limitingConeAngle', + 'bAz' => 'baz', + 'patterncontentunits' => 'patternContentUnits', + ); + + foreach ($tests as $input => $expected) { + $this->assertEquals($expected, Elements::normalizeSvgAttribute($input)); + } + } + + public function testNormalizeMathMlAttribute() + { + $tests = array( + 'foo' => 'foo', + 'definitionurl' => 'definitionURL', + 'BAR' => 'bar', + ); + + foreach ($tests as $input => $expected) { + $this->assertEquals($expected, Elements::normalizeMathMlAttribute($input)); + } + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Fixtures/encoding/utf-8.html b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Fixtures/encoding/utf-8.html new file mode 100644 index 000000000..fa5a029ce --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Fixtures/encoding/utf-8.html @@ -0,0 +1,9 @@ + + + + + + +

      Žťčýů

      + + diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Fixtures/encoding/windows-1252.html b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Fixtures/encoding/windows-1252.html new file mode 100644 index 000000000..f0132da5d --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Fixtures/encoding/windows-1252.html @@ -0,0 +1,9 @@ + + + + + + +

      + + diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Html5Test.html b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Html5Test.html new file mode 100644 index 000000000..a976e8be9 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Html5Test.html @@ -0,0 +1,10 @@ + + + + + Test + + +

      This is a test.

      + + \ No newline at end of file diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Html5Test.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Html5Test.php new file mode 100644 index 000000000..ed66d8af2 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Html5Test.php @@ -0,0 +1,492 @@ +html5 = $this->getInstance(); + } + + /** + * Parse and serialize a string. + */ + protected function cycle($html) + { + $dom = $this->html5->loadHTML('' . $html . ''); + $out = $this->html5->saveHTML($dom); + + return $out; + } + + protected function cycleFragment($fragment) + { + $dom = $this->html5->loadHTMLFragment($fragment); + $out = $this->html5->saveHTML($dom); + + return $out; + } + + public function testImageTagsInSvg() + { + $html = ' + + + foo + + + + + + + '; + $doc = $this->html5->loadHTML($html); + $this->assertInstanceOf('DOMElement', $doc->getElementsByTagName('image')->item(0)); + $this->assertEmpty($this->html5->getErrors()); + } + + public function testLoadOptions() + { + // doc + $dom = $this->html5->loadHTML($this->wrap(''), array( + 'implicitNamespaces' => array('t' => 'http://example.com'), + 'xmlNamespaces' => true, + )); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + $this->assertFalse($this->html5->hasErrors()); + + $xpath = new \DOMXPath($dom); + $xpath->registerNamespace('t', 'http://example.com'); + $this->assertEquals(1, $xpath->query('//t:tag')->length); + + // doc fragment + $frag = $this->html5->loadHTMLFragment('', array( + 'implicitNamespaces' => array('t' => 'http://example.com'), + 'xmlNamespaces' => true, + )); + $this->assertInstanceOf('\DOMDocumentFragment', $frag); + $this->assertEmpty($this->html5->getErrors()); + $this->assertFalse($this->html5->hasErrors()); + + $frag->ownerDocument->appendChild($frag); + $xpath = new \DOMXPath($frag->ownerDocument); + $xpath->registerNamespace('t', 'http://example.com'); + $this->assertEquals(1, $xpath->query('//t:tag', $frag)->length); + } + + public function testEncodingUtf8() + { + $dom = $this->html5->load(__DIR__ . '/Fixtures/encoding/utf-8.html'); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + $this->assertFalse($this->html5->hasErrors()); + + $this->assertContains('Žťčýů', $dom->saveHTML()); + } + + public function testEncodingWindows1252() + { + $dom = $this->html5->load(__DIR__ . '/Fixtures/encoding/windows-1252.html', array( + 'encoding' => 'Windows-1252', + )); + + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + $this->assertFalse($this->html5->hasErrors()); + + $dumpedAsUtf8 = mb_convert_encoding($dom->saveHTML(), 'UTF-8', 'Windows-1252'); + $this->assertNotFalse(mb_strpos($dumpedAsUtf8, 'Ž')); + $this->assertNotFalse(mb_strpos($dumpedAsUtf8, 'è')); + $this->assertNotFalse(mb_strpos($dumpedAsUtf8, 'ý')); + $this->assertNotFalse(mb_strpos($dumpedAsUtf8, 'ù')); + } + + public function testErrors() + { + $dom = $this->html5->loadHTML(''); + $this->assertInstanceOf('\DOMDocument', $dom); + + $this->assertNotEmpty($this->html5->getErrors()); + $this->assertTrue($this->html5->hasErrors()); + } + + public function testLoad() + { + $dom = $this->html5->load(__DIR__ . '/Html5Test.html'); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + $this->assertFalse($this->html5->hasErrors()); + + $file = fopen(__DIR__ . '/Html5Test.html', 'r'); + $dom = $this->html5->load($file); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + + $dom = $this->html5->loadHTMLFile(__DIR__ . '/Html5Test.html'); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + } + + public function testLoadHTML() + { + $contents = file_get_contents(__DIR__ . '/Html5Test.html'); + $dom = $this->html5->loadHTML($contents); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + } + + public function testLoadHTMLWithComments() + { + $contents = ' + +'; + + $dom = $this->html5->loadHTML($contents); + $this->assertInstanceOf('\DOMDocument', $dom); + + $expected = ' + +'; + $this->assertEquals($expected, $this->html5->saveHTML($dom)); + } + + public function testLoadHTMLFragment() + { + $fragment = '
      Baz
      '; + $dom = $this->html5->loadHTMLFragment($fragment); + $this->assertInstanceOf('\DOMDocumentFragment', $dom); + $this->assertEmpty($this->html5->getErrors()); + } + + public function testSaveHTML() + { + $dom = $this->html5->load(__DIR__ . '/Html5Test.html'); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + + $saved = $this->html5->saveHTML($dom); + $this->assertRegExp('|

      This is a test.

      |', $saved); + } + + public function testSaveHTMLFragment() + { + $fragment = '
      Baz
      '; + $dom = $this->html5->loadHTMLFragment($fragment); + + $string = $this->html5->saveHTML($dom); + $this->assertEquals($fragment, $string); + } + + public function testSave() + { + $dom = $this->html5->load(__DIR__ . '/Html5Test.html'); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + + // Test resource + $file = fopen('php://temp', 'w'); + $this->html5->save($dom, $file); + $content = stream_get_contents($file, -1, 0); + $this->assertRegExp('|

      This is a test.

      |', $content); + + // Test file + $tmpfname = tempnam(sys_get_temp_dir(), 'html5-php'); + $this->html5->save($dom, $tmpfname); + $content = file_get_contents($tmpfname); + $this->assertRegExp('|

      This is a test.

      |', $content); + unlink($tmpfname); + } + + // This test reads a document into a dom, turn the dom into a document, + // then tries to read that document again. This makes sure we are reading, + // and generating a document that works at a high level. + public function testItWorks() + { + $dom = $this->html5->load(__DIR__ . '/Html5Test.html'); + $this->assertInstanceOf('\DOMDocument', $dom); + $this->assertEmpty($this->html5->getErrors()); + + $saved = $this->html5->saveHTML($dom); + + $dom2 = $this->html5->loadHTML($saved); + $this->assertInstanceOf('\DOMDocument', $dom2); + $this->assertEmpty($this->html5->getErrors()); + } + + public function testConfig() + { + $html5 = $this->getInstance(); + $options = $html5->getOptions(); + $this->assertEquals(false, $options['encode_entities']); + + $html5 = $this->getInstance(array( + 'foo' => 'bar', + 'encode_entities' => true, + )); + $options = $html5->getOptions(); + $this->assertEquals('bar', $options['foo']); + $this->assertEquals(true, $options['encode_entities']); + + // Need to reset to original so future tests pass as expected. + // $this->getInstance()->setOption('encode_entities', false); + } + + public function testSvg() + { + $dom = $this->html5->loadHTML( + ' + + +
      foo bar baz
      + + + + + + + Test Text. + + + + + '); + + $this->assertEmpty($this->html5->getErrors()); + + // Test a mixed case attribute. + $list = $dom->getElementsByTagName('svg'); + $this->assertNotEmpty($list->length); + $svg = $list->item(0); + $this->assertEquals('0 0 3 2', $svg->getAttribute('viewBox')); + $this->assertFalse($svg->hasAttribute('viewbox')); + + // Test a mixed case tag. + // Note: getElementsByTagName is not case sensitive. + $list = $dom->getElementsByTagName('textPath'); + $this->assertNotEmpty($list->length); + $textPath = $list->item(0); + $this->assertEquals('textPath', $textPath->tagName); + $this->assertNotEquals('textpath', $textPath->tagName); + + $html = $this->html5->saveHTML($dom); + $this->assertRegExp('||', $html); + $this->assertRegExp('||', $html); + } + + public function testMathMl() + { + $dom = $this->html5->loadHTML( + ' + + +
      foo bar baz
      + + x + + ± + + y + + + '); + + $this->assertEmpty($this->html5->getErrors()); + $list = $dom->getElementsByTagName('math'); + $this->assertNotEmpty($list->length); + + $list = $dom->getElementsByTagName('div'); + $this->assertNotEmpty($list->length); + $div = $list->item(0); + $this->assertEquals('http://example.com', $div->getAttribute('definitionurl')); + $this->assertFalse($div->hasAttribute('definitionURL')); + $list = $dom->getElementsByTagName('csymbol'); + $csymbol = $list->item(0); + $this->assertEquals('http://www.example.com/mathops/multiops.html#plusminus', $csymbol->getAttribute('definitionURL')); + $this->assertFalse($csymbol->hasAttribute('definitionurl')); + + $html = $this->html5->saveHTML($dom); + $this->assertRegExp('||', $html); + $this->assertRegExp('|y|', $html); + } + + public function testUnknownElements() + { + // The : should not have special handling accourding to section 2.9 of the + // spec. This is differenant than XML. Since we don't know these elements + // they are handled as normal elements. Note, to do this is really + // an invalid example and you should not embed prefixed xml in html5. + $dom = $this->html5->loadHTMLFragment( + ' + Big rectangle thing + 40 + 80 + + um, yeah'); + + $this->assertEmpty($this->html5->getErrors()); + $markup = $this->html5->saveHTML($dom); + $this->assertRegExp('|Big rectangle thing|', $markup); + $this->assertRegExp('|um, yeah|', $markup); + } + + public function testElements() + { + // Should have content. + $res = $this->cycle('
      FOO
      '); + $this->assertRegExp('|
      FOO
      |', $res); + + // Should be empty + $res = $this->cycle(''); + $this->assertRegExp('||', $res); + + // Should have content. + $res = $this->cycleFragment('
      FOO
      '); + $this->assertRegExp('|
      FOO
      |', $res); + + // Should be empty + $res = $this->cycleFragment(''); + $this->assertRegExp('||', $res); + + // Elements with dashes and underscores + $res = $this->cycleFragment(''); + $this->assertRegExp('||', $res); + $res = $this->cycleFragment(''); + $this->assertRegExp('||', $res); + + // Should have no closing tag. + $res = $this->cycle('
      '); + $this->assertRegExp('|
      |', $res); + } + + public function testAttributes() + { + $res = $this->cycle(''); + $this->assertContains('', $res); + + $res = $this->cycle('
      FOO
      '); + $this->assertRegExp('|
      FOO
      |', $res); + + // XXX: Note that spec does NOT require attrs in the same order. + $res = $this->cycle('
      FOO
      '); + $this->assertRegExp('|
      FOO
      |', $res); + + $res = $this->cycle('
      FOO
      '); + $this->assertRegExp('|
      FOO
      |', $res); + + $res = $this->cycleFragment('
      FOO
      '); + $this->assertRegExp('|
      FOO
      |', $res); + + // XXX: Note that spec does NOT require attrs in the same order. + $res = $this->cycleFragment('
      FOO
      '); + $this->assertRegExp('|
      FOO
      |', $res); + + $res = $this->cycleFragment('
      FOO
      '); + $this->assertRegExp('|
      FOO
      |', $res); + } + + public function testPCData() + { + $res = $this->cycle('This is a test.'); + $this->assertRegExp('|This is a test.|', $res); + + $res = $this->cycleFragment('This is a test.'); + $this->assertRegExp('|This is a test.|', $res); + + $res = $this->cycle('This + is + a + test.'); + + // Check that newlines are there, but don't count spaces. + $this->assertRegExp('|This\n\s*is\n\s*a\n\s*test.|', $res); + + $res = $this->cycleFragment('This + is + a + test.'); + + // Check that newlines are there, but don't count spaces. + $this->assertRegExp('|This\n\s*is\n\s*a\n\s*test.|', $res); + + $res = $this->cycle('This is a test.'); + $this->assertRegExp('|This is a test.|', $res); + + $res = $this->cycleFragment('This is a test.'); + $this->assertRegExp('|This is a test.|', $res); + } + + public function testUnescaped() + { + $res = $this->cycle(''); + $this->assertRegExp('|2 < 1|', $res); + + $res = $this->cycle(''); + $this->assertRegExp('|div>div>div|', $res); + + $res = $this->cycleFragment(''); + $this->assertRegExp('|2 < 1|', $res); + + $res = $this->cycleFragment(''); + $this->assertRegExp('|div>div>div|', $res); + } + + public function testEntities() + { + $res = $this->cycle('Apples & bananas.'); + $this->assertRegExp('|Apples & bananas.|', $res); + + $res = $this->cycleFragment('Apples & bananas.'); + $this->assertRegExp('|Apples & bananas.|', $res); + + $res = $this->cycleFragment('

      R&D

      '); + $this->assertRegExp('|R&D|', $res); + } + + public function testCaseSensitiveTags() + { + $dom = $this->html5->loadHTML( + '', + array( + 'xmlNamespaces' => true, + ) + ); + $out = $this->html5->saveHTML($dom); + $this->assertRegExp('||', $out); + } + + public function testComment() + { + $res = $this->cycle('ab'); + $this->assertRegExp('||', $res); + + $res = $this->cycleFragment('ab'); + $this->assertRegExp('||', $res); + } + + public function testCDATA() + { + $res = $this->cycle('a a test. ]]>b'); + $this->assertRegExp('| a test\. \]\]>|', $res); + + $res = $this->cycleFragment('a a test. ]]>b'); + $this->assertRegExp('| a test\. \]\]>|', $res); + } + + public function testAnchorTargetQueryParam() + { + $res = $this->cycle('https://domain.com/page.php?foo=bar&target=baz'); + $this->assertContains( + 'https://domain.com/page.php?foo=bar&target=baz', + $res + ); + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/CharacterReferenceTest.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/CharacterReferenceTest.php new file mode 100644 index 000000000..a5eee73c8 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/CharacterReferenceTest.php @@ -0,0 +1,44 @@ +assertEquals('&', CharacterReference::lookupName('amp')); + $this->assertEquals('<', CharacterReference::lookupName('lt')); + $this->assertEquals('>', CharacterReference::lookupName('gt')); + $this->assertEquals('"', CharacterReference::lookupName('quot')); + $this->assertEquals('∌', CharacterReference::lookupName('NotReverseElement')); + + $this->assertNull(CharacterReference::lookupName('StinkyCheese')); + } + + public function testLookupHex() + { + $this->assertEquals('<', CharacterReference::lookupHex('3c')); + $this->assertEquals('<', CharacterReference::lookupHex('003c')); + $this->assertEquals('&', CharacterReference::lookupHex('26')); + $this->assertEquals('}', CharacterReference::lookupHex('7d')); + $this->assertEquals('Σ', CharacterReference::lookupHex('3A3')); + $this->assertEquals('Σ', CharacterReference::lookupHex('03A3')); + $this->assertEquals('Σ', CharacterReference::lookupHex('3a3')); + $this->assertEquals('Σ', CharacterReference::lookupHex('03a3')); + } + + public function testLookupDecimal() + { + $this->assertEquals('&', CharacterReference::lookupDecimal(38)); + $this->assertEquals('&', CharacterReference::lookupDecimal('38')); + $this->assertEquals('<', CharacterReference::lookupDecimal(60)); + $this->assertEquals('Σ', CharacterReference::lookupDecimal(931)); + $this->assertEquals('Σ', CharacterReference::lookupDecimal('0931')); + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/DOMTreeBuilderTest.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/DOMTreeBuilderTest.php new file mode 100644 index 000000000..659378c68 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/DOMTreeBuilderTest.php @@ -0,0 +1,743 @@ +parse(); + $this->errors = $treeBuilder->getErrors(); + + return $treeBuilder->document(); + } + + /** + * Utility function for parsing a fragment of HTML5. + */ + protected function parseFragment($string) + { + $treeBuilder = new DOMTreeBuilder(true); + $scanner = new Scanner($string); + $parser = new Tokenizer($scanner, $treeBuilder); + + $parser->parse(); + $this->errors = $treeBuilder->getErrors(); + + return $treeBuilder->fragment(); + } + + public function testDocument() + { + $html = ''; + $doc = $this->parse($html); + + $this->assertEquals('UTF-8', $doc->encoding); + $this->assertInstanceOf('\DOMDocument', $doc); + $this->assertEquals('html', $doc->documentElement->tagName); + $this->assertEquals('http://www.w3.org/1999/xhtml', $doc->documentElement->namespaceURI); + } + + public function testBareAmpersand() + { + $html = " + + + + + + + + "; + $doc = $this->parse($html); + + $this->assertEmpty($this->errors); + $this->assertXmlStringEqualsXmlString(' + + + + + + + + ', $doc->saveXML()); + } + + public function testBareAmpersandNotAllowedInAttributes() + { + $html = " + + + + + + "; + $doc = $this->parse($html); + + $this->assertCount(2, $this->errors); + $this->assertXmlStringEqualsXmlString(' + + + + + + ', $doc->saveXML()); + } + + public function testBareAmpersandNotAllowedInBody() + { + $html = ' + + + a&b + a&= + a&=c + a&=9 + a&+ + a& -- valid + + '; + $doc = $this->parse($html); + + $this->assertCount(5, $this->errors); + $this->assertXmlStringEqualsXmlString(' + + + a&b + a&= + a&=c + a&=9 + a&+ + a& -- valid + + ', $doc->saveXML()); + } + + public function testEntityAtEndOfFile() + { + $fragment = $this->parseFragment('&#'); + $this->assertInstanceOf('DOMDocumentFragment', $fragment); + $this->assertSame('&#', $fragment->textContent); + $this->assertEquals('Line 1, Col 2: Expected &#DEC; &#HEX;, got EOF', $this->errors[0]); + } + + public function testStrangeCapitalization() + { + $html = ' + + + Hello, world! + + TheBody + '; + $doc = $this->parse($html); + + $this->assertInstanceOf('\DOMDocument', $doc); + $this->assertEquals('html', $doc->documentElement->tagName); + + $xpath = new \DOMXPath($doc); + $xpath->registerNamespace('x', 'http://www.w3.org/1999/xhtml'); + + $this->assertEquals('Hello, world!', $xpath->query('//x:title')->item(0)->nodeValue); + $this->assertEquals('foo', $xpath->query('//x:script')->item(0)->nodeValue); + } + + public function testDocumentWithDisabledNamespaces() + { + $html = ''; + $doc = $this->parse($html, array('disable_html_ns' => true)); + + $this->assertInstanceOf('\DOMDocument', $doc); + $this->assertEquals('html', $doc->documentElement->tagName); + $this->assertNull($doc->documentElement->namespaceURI); + } + + public function testDocumentWithATargetDocument() + { + $targetDom = new \DOMDocument(); + + $html = ''; + $doc = $this->parse($html, array('target_document' => $targetDom)); + + $this->assertInstanceOf('\DOMDocument', $doc); + $this->assertSame($doc, $targetDom); + $this->assertEquals('html', $doc->documentElement->tagName); + } + + public function testDocumentFakeAttrAbsence() + { + $html = 'foo'; + $doc = $this->parse($html, array('xmlNamespaces' => true)); + + $xp = new \DOMXPath($doc); + $this->assertEquals(0, $xp->query('//@html5-php-fake-id-attribute')->length); + } + + public function testFragment() + { + $html = '
      test
      test2'; + $doc = $this->parseFragment($html); + + $this->assertInstanceOf('\DOMDocumentFragment', $doc); + $this->assertTrue($doc->hasChildNodes()); + $this->assertEquals('div', $doc->childNodes->item(0)->tagName); + $this->assertEquals('test', $doc->childNodes->item(0)->textContent); + $this->assertEquals('span', $doc->childNodes->item(1)->tagName); + $this->assertEquals('test2', $doc->childNodes->item(1)->textContent); + } + + public function testElements() + { + $html = ''; + $doc = $this->parse($html); + $root = $doc->documentElement; + + $this->assertEquals('html', $root->tagName); + $this->assertEquals('html', $root->localName); + $this->assertEquals('html', $root->nodeName); + + $this->assertEquals(2, $root->childNodes->length); + $kids = $root->childNodes; + + $this->assertEquals('head', $kids->item(0)->tagName); + $this->assertEquals('body', $kids->item(1)->tagName); + + $head = $kids->item(0); + $this->assertEquals(1, $head->childNodes->length); + $this->assertEquals('title', $head->childNodes->item(0)->tagName); + } + + public function testImplicitNamespaces() + { + $dom = $this->parse('foo'); + $a = $dom->getElementsByTagName('a')->item(0); + $attr = $a->getAttributeNode('xlink:href'); + $this->assertEquals('http://www.w3.org/1999/xlink', $attr->namespaceURI); + + $dom = $this->parse('foo'); + $a = $dom->getElementsByTagName('a')->item(0); + $attr = $a->getAttributeNode('xml:base'); + $this->assertEquals('http://www.w3.org/XML/1998/namespace', $attr->namespaceURI); + } + + public function testCustomImplicitNamespaces() + { + $dom = $this->parse('foo', array( + 'implicitNamespaces' => array( + 't' => 'http://www.example.com', + ), + )); + $a = $dom->getElementsByTagName('a')->item(0); + $attr = $a->getAttributeNode('t:href'); + $this->assertEquals('http://www.example.com', $attr->namespaceURI); + + $dom = $this->parse('foo', array( + 'implicitNamespaces' => array( + 't' => 'http://www.example.com', + ), + )); + $list = $dom->getElementsByTagNameNS('http://www.example.com', 'a'); + $this->assertEquals(1, $list->length); + } + + public function testXmlNamespaces() + { + $dom = $this->parse( + ' + + foo + +
      foo
      + ', array( + 'xmlNamespaces' => true, + )); + $a = $dom->getElementsByTagName('a')->item(0); + $attr = $a->getAttributeNode('t:href'); + $this->assertEquals('http://www.example.com', $attr->namespaceURI); + + $list = $dom->getElementsByTagNameNS('http://www.example.com', 'body'); + $this->assertEquals(1, $list->length); + } + + public function testXmlNamespaceNesting() + { + $dom = $this->parse( + ' + + + + + + +
      + + + + ', array( + 'xmlNamespaces' => true, + )); + + $this->assertEmpty($this->errors); + + $div = $dom->getElementById('div'); + $this->assertEquals('http://www.w3.org/1999/xhtml', $div->namespaceURI); + + $body = $dom->getElementById('body'); + $this->assertEquals('http://www.w3.org/1999/xhtml', $body->namespaceURI); + + $bar1 = $dom->getElementById('bar1'); + $this->assertEquals('http://www.prefixed.com/bar1', $bar1->namespaceURI); + + $bar2 = $dom->getElementById('bar2'); + $this->assertEquals('http://www.prefixed.com/bar2', $bar2->namespaceURI); + + $bar3 = $dom->getElementById('bar3'); + $this->assertEquals('http://www.w3.org/1999/xhtml', $bar3->namespaceURI); + + $bar4 = $dom->getElementById('bar4'); + $this->assertEquals('http://www.prefixed.com/bar4', $bar4->namespaceURI); + + $svg = $dom->getElementById('svg'); + $this->assertEquals('http://www.w3.org/2000/svg', $svg->namespaceURI); + + $prefixed = $dom->getElementById('prefixed'); + $this->assertEquals('http://www.prefixed.com', $prefixed->namespaceURI); + + $prefixed = $dom->getElementById('bar5'); + $this->assertEquals('http://www.prefixed.com/xn', $prefixed->namespaceURI); + + $prefixed = $dom->getElementById('bar5_x'); + $this->assertEquals('http://www.prefixed.com/bar5_x', $prefixed->namespaceURI); + } + + public function testMoveNonInlineElements() + { + $doc = $this->parse('

      line1


      line2

      '); + $this->assertEquals('

      line1


      line2', $doc->saveXML($doc->documentElement), 'Move non-inline elements outside of inline containers.'); + + $doc = $this->parse('

      line1

      line2

      '); + $this->assertEquals('

      line1

      line2
      ', $doc->saveXML($doc->documentElement), 'Move non-inline elements outside of inline containers.'); + } + + public function testAttributes() + { + $html = " + + + + "; + $doc = $this->parse($html); + $root = $doc->documentElement; + + $body = $root->GetElementsByTagName('body')->item(0); + $this->assertEquals('body', $body->tagName); + $this->assertTrue($body->hasAttributes()); + $this->assertEquals('a', $body->getAttribute('id')); + $this->assertEquals('b c', $body->getAttribute('class')); + + $body2 = $doc->getElementById('a'); + $this->assertEquals('body', $body2->tagName); + $this->assertEquals('a', $body2->getAttribute('id')); + } + + public function testSVGAttributes() + { + $html = " + + + + foo + + "; + $doc = $this->parse($html); + $root = $doc->documentElement; + + $svg = $root->getElementsByTagName('svg')->item(0); + $this->assertTrue($svg->hasAttribute('viewBox')); + + $rect = $root->getElementsByTagName('rect')->item(0); + $this->assertTrue($rect->hasAttribute('textLength')); + + $ac = $root->getElementsByTagName('animateColor'); + $this->assertEquals(1, $ac->length); + } + + public function testMathMLAttribute() + { + $html = ' + + + + x + + ± + + y + + + '; + + $doc = $this->parse($html); + $root = $doc->documentElement; + + $csymbol = $root->getElementsByTagName('csymbol')->item(0); + $this->assertTrue($csymbol->hasAttribute('definitionURL')); + } + + public function testMissingHtmlTag() + { + $html = 'test'; + $doc = $this->parse($html); + + $this->assertEquals('html', $doc->documentElement->tagName); + $this->assertEquals('title', $doc->documentElement->childNodes->item(0)->tagName); + } + + public function testComment() + { + $html = ''; + + $doc = $this->parse($html); + + $comment = $doc->documentElement->childNodes->item(0); + $this->assertEquals(XML_COMMENT_NODE, $comment->nodeType); + $this->assertEquals('Hello World.', $comment->data); + + $html = ''; + $doc = $this->parse($html); + + $comment = $doc->childNodes->item(1); + $this->assertEquals(XML_COMMENT_NODE, $comment->nodeType); + $this->assertEquals('Hello World.', $comment->data); + + $comment = $doc->childNodes->item(2); + $this->assertEquals(XML_ELEMENT_NODE, $comment->nodeType); + $this->assertEquals('html', $comment->tagName); + } + + public function testCDATA() + { + $html = 'test'; + $doc = $this->parse($html); + + $wrapper = $doc->getElementsByTagName('math')->item(0); + $this->assertEquals(1, $wrapper->childNodes->length); + $cdata = $wrapper->childNodes->item(0); + $this->assertEquals(XML_CDATA_SECTION_NODE, $cdata->nodeType); + $this->assertEquals('test', $cdata->data); + } + + public function testText() + { + $html = 'test'; + $doc = $this->parse($html); + + $wrapper = $doc->getElementsByTagName('math')->item(0); + $this->assertEquals(1, $wrapper->childNodes->length); + $data = $wrapper->childNodes->item(0); + $this->assertEquals(XML_TEXT_NODE, $data->nodeType); + $this->assertEquals('test', $data->data); + + // The DomTreeBuilder has special handling for text when in before head mode. + $html = ' + Foo'; + $doc = $this->parse($html); + $this->assertEquals('Line 0, Col 0: Unexpected text. Ignoring: Foo', $this->errors[0]); + $headElement = $doc->documentElement->firstChild; + $this->assertEquals('head', $headElement->tagName); + } + + public function testParseErrors() + { + $html = 'test'; + $doc = $this->parse($html); + + // We're JUST testing that we can access errors. Actual testing of + // error messages happen in the Tokenizer's tests. + $this->assertGreaterThan(0, count($this->errors)); + $this->assertTrue(is_string($this->errors[0])); + } + + public function testProcessingInstruction() + { + // Test the simple case, which is where PIs are inserted into the DOM. + $doc = $this->parse('<!DOCTYPE html><html><?foo bar?>'); + $this->assertEquals(1, $doc->documentElement->childNodes->length); + $pi = $doc->documentElement->firstChild; + $this->assertInstanceOf('\DOMProcessingInstruction', $pi); + $this->assertEquals('foo', $pi->nodeName); + $this->assertEquals('bar', $pi->data); + + // Leading xml PIs should be ignored. + $doc = $this->parse('<?xml version="1.0"?><!DOCTYPE html><html><head></head></html>'); + + $this->assertEquals(2, $doc->childNodes->length); + $this->assertInstanceOf('\DOMDocumentType', $doc->childNodes->item(0)); + $this->assertInstanceOf('\DOMElement', $doc->childNodes->item(1)); + } + + public function testAutocloseP() + { + $html = '<!DOCTYPE html><html><body><p><figure></body></html>'; + $doc = $this->parse($html); + + $p = $doc->getElementsByTagName('p')->item(0); + $this->assertEquals(0, $p->childNodes->length); + $this->assertEquals('figure', $p->nextSibling->tagName); + } + + public function testAutocloseLI() + { + $html = '<!doctype html> + <html lang="en"> + <body> + <ul><li>Foo<li>Bar<li>Baz</ul> + </body> + </html>'; + + $doc = $this->parse($html); + $length = $doc->getElementsByTagName('ul')->item(0)->childNodes->length; + $this->assertEquals(3, $length); + } + + public function testMathML() + { + $html = '<!doctype html> + <html lang="en"> + <body> + <math xmlns="http://www.w3.org/1998/Math/MathML"> + <mi>x</mi> + <csymbol definitionurl="http://www.example.com/mathops/multiops.html#plusminus"> + <mo>&PlusMinus;</mo> + </csymbol> + <mi>y</mi> + </math> + </body> + </html>'; + + $doc = $this->parse($html); + $math = $doc->getElementsByTagName('math')->item(0); + $this->assertEquals('math', $math->tagName); + $this->assertEquals('math', $math->nodeName); + $this->assertEquals('math', $math->localName); + $this->assertEquals('http://www.w3.org/1998/Math/MathML', $math->namespaceURI); + } + + public function testSVG() + { + $html = '<!doctype html> + <html lang="en"> + <body> + <svg width="150" height="100" viewBox="0 0 3 2" xmlns="http://www.w3.org/2000/svg"> + <rect width="1" height="2" x="2" fill="#d2232c" /> + <text font-family="Verdana" font-size="32"> + <textpath xlink:href="#Foo"> + Test Text. + </textPath> + </text> + </svg> + </body> + </html>'; + + $doc = $this->parse($html); + $svg = $doc->getElementsByTagName('svg')->item(0); + $this->assertEquals('svg', $svg->tagName); + $this->assertEquals('svg', $svg->nodeName); + $this->assertEquals('svg', $svg->localName); + $this->assertEquals('http://www.w3.org/2000/svg', $svg->namespaceURI); + + $textPath = $doc->getElementsByTagName('textPath')->item(0); + $this->assertEquals('textPath', $textPath->tagName); + } + + public function testNoScript() + { + $html = '<!DOCTYPE html><html><head><noscript>No JS</noscript></head></html>'; + $doc = $this->parse($html); + $this->assertEmpty($this->errors); + $noscript = $doc->getElementsByTagName('noscript')->item(0); + $this->assertEquals('noscript', $noscript->tagName); + + $html = '<!DOCTYPE html><html><body><noscript><p>No JS</p></noscript></body></html>'; + $doc = $this->parse($html); + $this->assertEmpty($this->errors); + $p = $doc->getElementsByTagName('p')->item(0); + $this->assertEquals('p', $p->tagName); + } + + /** + * Regression for issue #13. + */ + public function testRegressionHTMLNoBody() + { + $html = '<!DOCTYPE html><html><span id="test">Test</span></html>'; + $doc = $this->parse($html); + $span = $doc->getElementById('test'); + + $this->assertEmpty($this->errors); + + $this->assertEquals('span', $span->tagName); + $this->assertEquals('Test', $span->textContent); + } + + public function testInstructionProcessor() + { + $string = '<!DOCTYPE html><html><?foo bar ?></html>'; + + $treeBuilder = new DOMTreeBuilder(); + $is = new InstructionProcessorMock(); + $treeBuilder->setInstructionProcessor($is); + + $scanner = new Scanner($string); + $parser = new Tokenizer($scanner, $treeBuilder); + + $parser->parse(); + $dom = $treeBuilder->document(); + $div = $dom->getElementsByTagName('div')->item(0); + + $this->assertEquals(1, $is->count); + $this->assertEquals('foo', $is->name); + $this->assertEquals('bar ', $is->data); + $this->assertEquals('div', $div->tagName); + $this->assertEquals('foo', $div->textContent); + } + + public function testSelectGroupedOptions() + { + $html = <<<EOM +<!DOCTYPE html> +<html> + <head> + <title>testSelectGroupedOptions</title> + </head> + <body> + <select> + <optgroup id="first" label="first"> + <option value="foo">foo</option> + <option value="bar">bar</option> + <option value="baz">baz</option> + </optgroup> + <optgroup id="second" label="second"> + <option value="lorem">lorem</option> + <option value="ipsum">ipsum</option> + </optgroup> + </select> + </body> +</html> +EOM; + $dom = $this->parse($html); + + $this->assertSame(3, $dom->getElementById('first')->getElementsByTagName('option')->length); + $this->assertSame(2, $dom->getElementById('second')->getElementsByTagName('option')->length); + } + + public function testVoidTag() + { + $html = <<<EOM +<!DOCTYPE html> +<html> + <head> + <title>testVoidTag</title> + <meta> + <meta> + </head> + <body></body> +</html> +EOM; + + $dom = $this->parse($html); + $this->assertSame(2, $dom->getElementsByTagName('meta')->length); + $this->assertSame(0, $dom->getElementsByTagName('meta')->item(0)->childNodes->length); + $this->assertSame(0, $dom->getElementsByTagName('meta')->item(1)->childNodes->length); + } + + public function testIgnoreSelfClosingTag() + { + $html = <<<EOM +<!DOCTYPE html> +<html> + <head> + <title>testIllegalSelfClosingTag</title> + </head> + <body> + <div /><span>Hello, World!</span></div> + </body> +</html> +EOM; + + $dom = $this->parse($html); + $this->assertSame(1, $dom->getElementsByTagName('div')->item(0)->childNodes->length); + } + + public function testIAudioInParagraph() + { + $html = <<<EOM +<!DOCTYPE html> +<html> + <head> + <title>testIllegalSelfClosingTag</title> + </head> + <body> + <p> + <audio preload="none" controls="controls"> + <source src="https://example.com/test.mp3" type="audio/mpeg" /> + Your browser does not support the audio element. + </audio> + </p> + </body> +</html>> +</html> +EOM; + + $dom = $this->parse($html); + $audio = $dom->getElementsByTagName('audio')->item(0); + + $this->assertSame('p', $audio->parentNode->nodeName); + $this->assertSame(3, $audio->childNodes->length); + } + + public function testClosingBr() + { + $html = <<<EOM +<!DOCTYPE html> +<html> + <head> + <title>testClosingBr</title> + </head> + <body> + <p> + This line ends with a normal line break <br class="attribute-should-be-retained"> + This line ends with a line break marked up as a closing tag </br class="attribute-should-be-discarded"> + </p> + </body> +</html>> +</html> +EOM; + + $dom = $this->parse($html); + + $this->assertSame(2, $dom->getElementsByTagName('br')->length); + $this->assertSame(1, $dom->getElementsByTagName('br')->item(0)->attributes->length); + $this->assertSame(0, $dom->getElementsByTagName('br')->item(1)->attributes->length); + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/EventStack.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/EventStack.php new file mode 100644 index 000000000..3d1de7708 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/EventStack.php @@ -0,0 +1,116 @@ +<?php + +namespace Masterminds\HTML5\Tests\Parser; + +use Masterminds\HTML5\Elements; +use Masterminds\HTML5\Parser\EventHandler; + +/** + * This testing class gathers events from a parser and builds a stack of events. + * It is useful for checking the output of a tokenizer. + * + * IMPORTANT: + * + * The startTag event also kicks the parser into TEXT_RAW when it encounters + * script or pre tags. This is to match the behavior required by the HTML5 spec, + * which says that the tree builder must tell the tokenizer when to switch states. + */ +class EventStack implements EventHandler +{ + protected $stack; + + public function __construct() + { + $this->stack = array(); + } + + /** + * Get the event stack. + */ + public function events() + { + return $this->stack; + } + + public function depth() + { + return count($this->stack); + } + + public function get($index) + { + return $this->stack[$index]; + } + + protected function store($event, $data = null) + { + $this->stack[] = array( + 'name' => $event, + 'data' => $data, + ); + } + + public function doctype($name, $type = 0, $id = null, $quirks = false) + { + $args = array( + $name, + $type, + $id, + $quirks, + ); + $this->store('doctype', $args); + } + + public function startTag($name, $attributes = array(), $selfClosing = false) + { + $args = func_get_args(); + $this->store('startTag', $args); + if ('pre' == $name || 'script' == $name) { + return Elements::TEXT_RAW; + } + } + + public function endTag($name) + { + $this->store('endTag', array( + $name, + )); + } + + public function comment($cdata) + { + $this->store('comment', array( + $cdata, + )); + } + + public function cdata($data) + { + $this->store('cdata', func_get_args()); + } + + public function text($cdata) + { + // fprintf(STDOUT, "Received TEXT event with: " . $cdata); + $this->store('text', array( + $cdata, + )); + } + + public function eof() + { + $this->store('eof'); + } + + public function parseError($msg, $line, $col) + { + // throw new EventStackParseError(sprintf("%s (line %d, col %d)", $msg, $line, $col)); + // $this->store(sprintf("%s (line %d, col %d)", $msg, $line, $col)); + $this->store('error', func_get_args()); + } + + public function processingInstruction($name, $data = null) + { + $this->store('pi', func_get_args()); + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/EventStackError.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/EventStackError.php new file mode 100644 index 000000000..05c0a498f --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/EventStackError.php @@ -0,0 +1,7 @@ +<?php + +namespace Masterminds\HTML5\Tests\Parser; + +class EventStackError extends \Exception +{ +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/InstructionProcessorMock.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/InstructionProcessorMock.php new file mode 100644 index 000000000..4637a802c --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/InstructionProcessorMock.php @@ -0,0 +1,26 @@ +<?php + +namespace Masterminds\HTML5\Tests\Parser; + +class InstructionProcessorMock implements \Masterminds\HTML5\InstructionProcessor +{ + public $name = null; + + public $data = null; + + public $count = 0; + + public function process(\DOMElement $element, $name, $data) + { + $this->name = $name; + $this->data = $data; + ++$this->count; + + $div = $element->ownerDocument->createElement('div'); + $div->nodeValue = 'foo'; + + $element->appendChild($div); + + return $div; + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/ScannerTest.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/ScannerTest.php new file mode 100644 index 000000000..9f75c4dba --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/ScannerTest.php @@ -0,0 +1,184 @@ +<?php +/** + * @file + * Test the Scanner. This requires the InputStream tests are all good. + */ + +namespace Masterminds\HTML5\Tests\Parser; + +use Masterminds\HTML5\Parser\StringInputStream; +use Masterminds\HTML5\Parser\Scanner; + +class ScannerTest extends \Masterminds\HTML5\Tests\TestCase +{ + /** + * A canary test to make sure the basics are setup and working. + */ + public function testConstructDeprecated() + { + $is = new StringInputStream('abc'); + $s = new Scanner($is); + + $this->assertInstanceOf('\Masterminds\HTML5\Parser\Scanner', $s); + } + + public function testConstruct() + { + $this->assertInstanceOf('\Masterminds\HTML5\Parser\Scanner', new Scanner('abc')); + } + + public function testNextDeprecated() + { + $s = new Scanner(new StringInputStream('abc')); + + $this->assertEquals('b', $s->next()); + $this->assertEquals('c', $s->next()); + } + + public function testNext() + { + $s = new Scanner('abc'); + + $this->assertEquals('b', $s->next()); + $this->assertEquals('c', $s->next()); + } + + public function testPosition() + { + $s = new Scanner('abc'); + + $this->assertEquals(0, $s->position()); + + $s->next(); + $this->assertEquals(1, $s->position()); + } + + public function testPeek() + { + $s = new Scanner('abc'); + + $this->assertEquals('b', $s->peek()); + + $s->next(); + $this->assertEquals('c', $s->peek()); + } + + public function testCurrent() + { + $s = new Scanner('abc'); + + // Before scanning the string begins the current is empty. + $this->assertEquals('a', $s->current()); + + $c = $s->next(); + $this->assertEquals('b', $s->current()); + + // Test movement through the string. + $c = $s->next(); + $this->assertEquals('c', $s->current()); + } + + public function testUnconsume() + { + $s = new Scanner('abcdefghijklmnopqrst'); + + // Get initial position. + $s->next(); + $start = $s->position(); + + // Move forward a bunch of positions. + $amount = 7; + for ($i = 0; $i < $amount; ++$i) { + $s->next(); + } + + // Roll back the amount we moved forward. + $s->unconsume($amount); + + $this->assertEquals($start, $s->position()); + } + + public function testGetHex() + { + $s = new Scanner('ab13ck45DE*'); + + $this->assertEquals('ab13c', $s->getHex()); + + $s->next(); + $this->assertEquals('45DE', $s->getHex()); + } + + public function testGetAsciiAlpha() + { + $s = new Scanner('abcdef1%mnop*'); + + $this->assertEquals('abcdef', $s->getAsciiAlpha()); + + // Move past the 1% to scan the next group of text. + $s->next(); + $s->next(); + $this->assertEquals('mnop', $s->getAsciiAlpha()); + } + + public function testGetAsciiAlphaNum() + { + $s = new Scanner('abcdef1ghpo#mn94op'); + + $this->assertEquals('abcdef1ghpo', $s->getAsciiAlphaNum()); + + // Move past the # to scan the next group of text. + $s->next(); + $this->assertEquals('mn94op', $s->getAsciiAlphaNum()); + } + + public function testGetNumeric() + { + $s = new Scanner('1784a 45 9867 #'); + + $this->assertEquals('1784', $s->getNumeric()); + + // Move past the 'a ' to scan the next group of text. + $s->next(); + $s->next(); + $this->assertEquals('45', $s->getNumeric()); + } + + public function testCurrentLine() + { + $s = new Scanner("1784a\n45\n9867 #\nThis is a test."); + + $this->assertEquals(1, $s->currentLine()); + + // Move to the next line. + $s->getAsciiAlphaNum(); + $s->next(); + $this->assertEquals(2, $s->currentLine()); + } + + public function testColumnOffset() + { + $s = new Scanner("1784a a\n45 9867 #\nThis is a test."); + + // Move the pointer to the space. + $s->getAsciiAlphaNum(); + $this->assertEquals(5, $s->columnOffset()); + + // We move the pointer ahead. There must be a better way to do this. + $s->next(); + $s->next(); + $s->next(); + $s->next(); + $s->next(); + $s->next(); + $this->assertEquals(3, $s->columnOffset()); + } + + public function testRemainingChars() + { + $string = "\n45\n9867 #\nThis is a test."; + $s = new Scanner("1784a\n45\n9867 #\nThis is a test."); + + $s->getAsciiAlphaNum(); + $this->assertEquals($string, $s->remainingChars()); + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/TokenizerTest.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/TokenizerTest.php new file mode 100644 index 000000000..5284d30df --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Parser/TokenizerTest.php @@ -0,0 +1,978 @@ +<?php + +namespace Masterminds\HTML5\Tests\Parser; + +use Masterminds\HTML5\Parser\UTF8Utils; +use Masterminds\HTML5\Parser\Scanner; +use Masterminds\HTML5\Parser\Tokenizer; + +class TokenizerTest extends \Masterminds\HTML5\Tests\TestCase +{ + // ================================================================ + // Additional assertions. + // ================================================================ + + /** + * Tests that an event matches both the event type and the expected value. + * + * @param string $type + * Expected event type + * @param string $expects + * The value expected in $event['data'][0] + */ + public function assertEventEquals($type, $expects, $event) + { + $this->assertEquals($type, $event['name'], "Event $type for " . print_r($event, true)); + if (is_array($expects)) { + $this->assertEquals($expects, $event['data'], "Event $type should equal " . print_r($expects, true) . ': ' . print_r($event, true)); + } else { + $d = (is_array($event['data']) ? $event['data'][0] : null); + $this->assertEquals($expects, $d, "Event $type should equal $expects: " . print_r($event, true)); + } + } + + /** + * Assert that a given event is 'error'. + */ + public function assertEventError($event) + { + $this->assertEquals('error', $event['name'], 'Expected error for event: ' . print_r($event, true)); + } + + /** + * Asserts that all of the tests are good. + * + * This loops through a map of tests/expectations and runs a few assertions on each test. + * + * Checks: + * - depth (if depth is > 0) + * - event name + * - matches on event 0. + */ + protected function isAllGood($name, $depth, $tests, $debug = false) + { + foreach ($tests as $try => $expects) { + if ($debug) { + fprintf(STDOUT, "%s expects %s\n", $try, print_r($expects, true)); + } + $e = $this->parse($try); + if ($depth > 0) { + $this->assertEquals($depth, $e->depth(), "Expected depth $depth for test $try." . print_r($e, true)); + } + $this->assertEventEquals($name, $expects, $e->get(0)); + } + } + + // ================================================================ + // Utility functions. + // ================================================================ + public function testParse() + { + list($tok, $events) = $this->createTokenizer(''); + + $tok->parse(); + $e1 = $events->get(0); + + $this->assertEquals(1, $events->Depth()); + $this->assertEquals('eof', $e1['name']); + } + + public function testWhitespace() + { + $spaces = ' '; + list($tok, $events) = $this->createTokenizer($spaces); + + $tok->parse(); + + $this->assertEquals(2, $events->depth()); + + $e1 = $events->get(0); + + $this->assertEquals('text', $e1['name']); + $this->assertEquals($spaces, $e1['data'][0]); + } + + public function testCharacterReference() + { + $good = array( + '&amp;' => '&', + '&#x0003c;' => '<', + '&#38;' => '&', + '&' => '&', + ); + $this->isAllGood('text', 2, $good); + + // Test with broken charref + $str = '&foo'; + $events = $this->parse($str); + $e1 = $events->get(0); + $this->assertEquals('error', $e1['name']); + + $str = '&#xfoo'; + $events = $this->parse($str); + $e1 = $events->get(0); + $this->assertEquals('error', $e1['name']); + + $str = '&#foo'; + $events = $this->parse($str); + $e1 = $events->get(0); + $this->assertEquals('error', $e1['name']); + + // FIXME: Once the text processor is done, need to verify that the + // tokens are transformed correctly into text. + } + + public function testBogusComment() + { + $bogus = array( + '</+this is a bogus comment. +>', + '<!+this is a bogus comment. !>', + '<!D OCTYPE foo bar>', + '<!DOCTYEP foo bar>', + '<![CADATA[ TEST ', + '', + ' Hello [[>', + '<!CDATA[[ test ', + '', + '<![CDATA[hellooooo hello', + '<? Hello World ?>', + '<? Hello World', + ); + foreach ($bogus as $str) { + $events = $this->parse($str); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('comment', $str, $events->get(1)); + } + } + + public function testEndTag() + { + $succeed = array( + '</a>' => 'a', + '</test>' => 'test', + '</test + >' => 'test', + '</thisIsTheTagThatDoesntEndItJustGoesOnAndOnMyFriend>' => 'thisisthetagthatdoesntenditjustgoesonandonmyfriend', + // See 8.2.4.10, which requires this and does not say error. + '</a<b>' => 'a<b', + ); + $this->isAllGood('endTag', 2, $succeed); + + // Recoverable failures + $fail = array( + '</a class="monkey">' => 'a', + '</a <b>' => 'a', + '</a <b <c>' => 'a', + '</a is the loneliest letter>' => 'a', + '</a' => 'a', + ); + foreach ($fail as $test => $result) { + $events = $this->parse($test); + $this->assertEquals(3, $events->depth()); + // Should have triggered an error. + $this->assertEventError($events->get(0)); + // Should have tried to parse anyway. + $this->assertEventEquals('endTag', $result, $events->get(1)); + } + + // BogoComments + $comments = array( + '</>' => '</>', + '</ >' => '</ >', + '</ a>' => '</ a>', + ); + foreach ($comments as $test => $result) { + $events = $this->parse($test); + $this->assertEquals(3, $events->depth()); + + // Should have triggered an error. + $this->assertEventError($events->get(0)); + + // Should have tried to parse anyway. + $this->assertEventEquals('comment', $result, $events->get(1)); + } + } + + public function testComment() + { + $good = array( + '<!--easy-->' => 'easy', + '<!-- 1 > 0 -->' => ' 1 > 0 ', + '<!-- --$i -->' => ' --$i ', + '<!----$i-->' => '--$i', + "<!--\nHello World.\na-->" => "\nHello World.\na", + '<!-- <!-- -->' => ' <!-- ', + ); + foreach ($good as $test => $expected) { + $events = $this->parse($test); + $this->assertEventEquals('comment', $expected, $events->get(0)); + } + + $fail = array( + '<!-->' => '', + '<!--Hello' => 'Hello', + "<!--\0Hello" => UTF8Utils::FFFD . 'Hello', + '<!--' => '', + ); + foreach ($fail as $test => $expected) { + $events = $this->parse($test); + $this->assertEquals(3, $events->depth()); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('comment', $expected, $events->get(1)); + } + } + + public function testCDATASection() + { + $good = array( + '<![CDATA[ This is a test. ' => ' This is a test. ', + 'CDATA' => 'CDATA', + ' ]] > ' => ' ]] > ', + ' ' => ' ', + ); + $this->isAllGood('cdata', 2, $good); + } + + public function testDoctype() + { + $good = array( + '' => array( + 'html', + 0, + null, + false, + ), + '' => array( + 'html', + 0, + null, + false, + ), + '' => array( + 'html', + 0, + null, + false, + ), + "" => array( + 'html', + 0, + null, + false, + ), + "" => array( + 'html', + 0, + null, + false, + ), + '' => array( + 'html', + EventStack::DOCTYPE_PUBLIC, + 'foo bar', + false, + ), + "" => array( + 'html', + EventStack::DOCTYPE_PUBLIC, + 'foo bar', + false, + ), + '' => array( + 'html', + EventStack::DOCTYPE_PUBLIC, + 'foo bar', + false, + ), + "" => array( + 'html', + EventStack::DOCTYPE_PUBLIC, + 'foo bar', + false, + ), + '' => array( + 'html', + EventStack::DOCTYPE_SYSTEM, + 'foo bar', + false, + ), + "" => array( + 'html', + EventStack::DOCTYPE_SYSTEM, + 'foo bar', + false, + ), + '' => array( + 'html', + EventStack::DOCTYPE_SYSTEM, + 'foo/bar', + false, + ), + "" => array( + 'html', + EventStack::DOCTYPE_SYSTEM, + 'foo bar', + false, + ), + ); + $this->isAllGood('doctype', 2, $good); + + $bad = array( + '' => array( + null, + EventStack::DOCTYPE_NONE, + null, + true, + ), + '' => array( + null, + EventStack::DOCTYPE_NONE, + null, + true, + ), + ' array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + ' array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + '' => array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + '' => array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + ' array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + + // Can't tell whether these are ids or ID types, since the context is chopped. + ' array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + '' => array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + ' array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + '' => array( + 'foo', + EventStack::DOCTYPE_NONE, + null, + true, + ), + + ' array( + 'html', + EventStack::DOCTYPE_SYSTEM, + 'foo bar', + true, + ), + '' => array( + 'html', + EventStack::DOCTYPE_SYSTEM, + 'foo bar', + true, + ), + ); + foreach ($bad as $test => $expects) { + $events = $this->parse($test); + // fprintf(STDOUT, $test . PHP_EOL); + $this->assertEquals(3, $events->depth(), "Counting events for '$test': " . print_r($events, true)); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('doctype', $expects, $events->get(1)); + } + } + + public function testProcessorInstruction() + { + $good = array( + '' => 'hph', + '' => array( + 'hph', + 'echo "Hello World"; ', + ), + "" => array( + 'hph', + "echo 'Hello World';\n", + ), + ); + $this->isAllGood('pi', 2, $good); + } + + /** + * This tests just simple tags. + */ + public function testSimpleTags() + { + $open = array( + '' => 'foo', + '' => 'foo', + '' => 'foo', + '' => 'foo', + "" => 'foo', + '' => 'foo:bar', + ); + $this->isAllGood('startTag', 2, $open); + + $selfClose = array( + '' => 'foo', + '' => 'foo', + '' => 'foo', + "" => 'foo', + '' => 'foo:bar', + ); + foreach ($selfClose as $test => $expects) { + $events = $this->parse($test); + $this->assertEquals(2, $events->depth(), "Counting events for '$test'" . print_r($events, true)); + $this->assertEventEquals('startTag', $expects, $events->get(0)); + $event = $events->get(0); + $this->assertTrue($event['data'][2]); + } + + $bad = array( + ' 'foo', + ' 'foo', + ' 'foo', + ' 'foo', + ); + + foreach ($bad as $test => $expects) { + $events = $this->parse($test); + $this->assertEquals(3, $events->depth(), "Counting events for '$test': " . print_r($events, true)); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('startTag', $expects, $events->get(1)); + } + } + + public function testTagsWithAttributeAndMissingName() + { + $cases = array( + '' => 'id', + '' => 'color', + "" => 'class', + '' => 'bgcolor', + '' => 'class', + ); + + foreach ($cases as $html => $expected) { + $events = $this->parse($html); + $this->assertEventError($events->get(0)); + $this->assertEventError($events->get(1)); + $this->assertEventError($events->get(2)); + $this->assertEventEquals('startTag', $expected, $events->get(3)); + $this->assertEventEquals('eof', null, $events->get(4)); + } + } + + public function testTagNotClosedAfterTagName() + { + $cases = array( + '' => array( + 'noscript', + 'img', + ), + '' => array( + 'center', + 'a', + ), + '' => array( + 'br', + 'br', + ), + ); + + foreach ($cases as $html => $expected) { + $events = $this->parse($html); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('startTag', $expected[0], $events->get(1)); + $this->assertEventEquals('startTag', $expected[1], $events->get(2)); + $this->assertEventEquals('eof', null, $events->get(3)); + } + + $events = $this->parse('02'); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('startTag', 'span', $events->get(1)); + $this->assertEventError($events->get(2)); + $this->assertEventEquals('text', '>02', $events->get(3)); + $this->assertEventEquals('endTag', 'span', $events->get(4)); + $this->assertEventEquals('eof', null, $events->get(5)); + + $events = $this->parse(''); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('startTag', 'p', $events->get(1)); + $this->assertEventEquals('endTag', 'p', $events->get(2)); + $this->assertEventEquals('eof', null, $events->get(3)); + + $events = $this->parse(''); + $this->assertEventEquals('startTag', 'strong', $events->get(0)); + $this->assertEventError($events->get(1)); + $this->assertEventEquals('startTag', 'wordpress', $events->get(2)); + $this->assertEventEquals('endTag', 'strong', $events->get(3)); + $this->assertEventEquals('eof', null, $events->get(4)); + + $events = $this->parse(''); + $this->assertEventError($events->get(0)); + $this->assertEventError($events->get(1)); + $this->assertEventError($events->get(2)); + $this->assertEventEquals('startTag', 'src', $events->get(3)); + $this->assertEventEquals('startTag', 'a', $events->get(4)); + $this->assertEventEquals('eof', null, $events->get(5)); + + $events = $this->parse(''); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('startTag', 'br', $events->get(1)); + $this->assertEventEquals('eof', null, $events->get(2)); + } + + public function testIllegalTagNames() + { + $cases = array( + '' => 'li', + '' => 'p', + '' => 'b', + '' => 'static', + '' => 'h', + '' => 'st', + ); + + foreach ($cases as $html => $expected) { + $events = $this->parse($html); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('startTag', $expected, $events->get(1)); + } + } + + public function testTagAttributes() + { + // Opening tags. + $good = array( + '' => array( + 'foo', + array( + 'bar' => 'baz', + ), + false, + ), + '' => array( + 'foo', + array( + 'bar' => ' baz ', + ), + false, + ), + "" => array( + 'foo', + array( + 'bar' => "\nbaz\n", + ), + false, + ), + "" => array( + 'foo', + array( + 'bar' => 'baz', + ), + false, + ), + '' => array( + 'foo', + array( + 'bar' => 'A full sentence.', + ), + false, + ), + "" => array( + 'foo', + array( + 'a' => '1', + 'b' => '2', + ), + false, + ), + "" => array( + 'foo', + array( + 'ns:bar' => 'baz', + ), + false, + ), + "" => array( + 'foo', + array( + 'a' => 'blue&red', + ), + false, + ), + "" => array( + 'foo', + array( + 'a' => 'blue&red', + ), + false, + ), + "" => array( + 'foo', + array( + 'a' => 'blue&&&red', + ), + false, + ), + "" => array( + 'foo', + array( + 'a' => 'blue&&red', + ), + false, + ), + "" => array( + 'foo', + array( + 'bar' => 'baz', + ), + false, + ), + '' => array( + 'doe', + array( + 'a' => null, + 'deer' => null, + ), + false, + ), + '' => array( + 'foo', + array( + 'bar' => 'baz', + ), + false, + ), + + // Updated for 8.1.2.3 + '' => array( + 'foo', + array( + 'bar' => 'baz', + ), + false, + ), + + // The spec allows an unquoted value '/'. This will not be a closing + // tag. + '' => array( + 'foo', + array( + 'bar' => '/', + ), + false, + ), + '' => array( + 'foo', + array( + 'bar' => 'baz/', + ), + false, + ), + ); + $this->isAllGood('startTag', 2, $good); + + // Self-closing tags. + $withEnd = array( + '' => array( + 'foo', + array( + 'bar' => 'baz', + ), + true, + ), + '' => array( + 'foo', + array( + 'bar' => 'baz', + ), + true, + ), + '' => array( + 'foo', + array( + 'bar' => 'BAZ', + ), + true, + ), + "" => array( + 'foo', + array( + 'a' => '1', + 'b' => '2', + 'c' => '3', + 'd' => null, + ), + true, + ), + ); + $this->isAllGood('startTag', 2, $withEnd); + + // Cause a parse error. + $bad = array( + // This will emit an entity lookup failure for &+dark. + "" => array( + 'foo', + array( + 'a' => 'blue&+dark', + ), + false, + ), + '' => array( + 'foo', + array( + 'bar' => null, + ), + false, + ), + '' => array( + 'foo', + array( + 'bar' => 'oh"', + ), + false, + ), + + // these attributes are ignored because of current implementation + // of method "DOMElement::setAttribute" + // see issue #23: https://github.com/Masterminds/html5-php/issues/23 + '' => array( + 'foo', + array(), + false, + ), + '' => array( + 'foo', + array(), + false, + ), + '' => array( + 'foo', + array(), + false, + ), + '' => array( + 'foo', + array(), + false, + ), + ) + ; + foreach ($bad as $test => $expects) { + $events = $this->parse($test); + $this->assertEquals(3, $events->depth(), "Counting events for '$test': " . print_r($events, true)); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('startTag', $expects, $events->get(1)); + } + + // Cause multiple parse errors. + $reallyBad = array( + '' => array( + 'foo', + array( + '=' => null, + '"bar"' => null, + ), + false, + ), + '' => array( + 'foo', + array(), + true, + ), + // character "&" in unquoted attribute shouldn't cause an infinite loop + '' => array( + 'foo', + array( + 'bar' => 'index.php?str=1&id=29', + ), + false, + ), + ); + foreach ($reallyBad as $test => $expects) { + $events = $this->parse($test); + // fprintf(STDOUT, $test . print_r($events, true)); + $this->assertEventError($events->get(0)); + $this->assertEventError($events->get(1)); + // $this->assertEventEquals('startTag', $expects, $events->get(1)); + } + + // Regression: Malformed elements should be detected. + // '' => array('foo', array('baz' => '1'), false), + $events = $this->parse(''); + $this->assertEventError($events->get(0)); + $this->assertEventEquals('startTag', array( + 'foo', + array( + 'baz' => '1', + ), + false, + ), $events->get(1)); + $this->assertEventEquals('startTag', array( + 'bar', + array(), + false, + ), $events->get(2)); + $this->assertEventEquals('endTag', array( + 'foo', + ), $events->get(3)); + } + + public function testRawText() + { + $good = array( + ' ' => 'abcd efg hijk lmnop', + '' => '', + '' => '<<<<<<<<', + '' => 'hello\nhello" => "\nhello&' => '&', + '' => '', + '' => '', + ); + foreach ($good as $test => $expects) { + $events = $this->parse($test); + $this->assertEventEquals('startTag', 'script', $events->get(0)); + $this->assertEventEquals('text', $expects, $events->get(1)); + $this->assertEventEquals('endTag', 'script', $events->get(2)); + } + + $bad = array( + ' + + +
      foo bar baz
      + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $script = $dom->getElementsByTagName('script'); + $r->element($script->item(0)); + $this->assertEquals( + '', stream_get_contents($stream, -1, 0)); + } + + public function testElementWithStyle() + { + $dom = $this->html5->loadHTML( + ' + + + + + +
      foo bar baz
      + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $style = $dom->getElementsByTagName('style'); + $r->element($style->item(0)); + $this->assertEquals('', stream_get_contents($stream, -1, 0)); + } + + public function testOpenTag() + { + $dom = $this->html5->loadHTML(' + + +
      foo bar baz
      + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('div'); + $m = $this->getProtectedMethod('openTag'); + $m->invoke($r, $list->item(0)); + $this->assertEquals('
      ', stream_get_contents($stream, -1, 0)); + } + + public function testCData() + { + $dom = $this->html5->loadHTML(' + + +
      + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('div'); + $r->cdata($list->item(0)->childNodes->item(0)); + $this->assertEquals('', stream_get_contents($stream, -1, 0)); + + $dom = $this->html5->loadHTML(' + + +
      + + '); + + $dom->getElementById('foo')->appendChild(new \DOMCdataSection(']]>Foo<[![CDATA test ]]>')); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + $list = $dom->getElementsByTagName('div'); + $r->cdata($list->item(0)->childNodes->item(0)); + + $this->assertEquals('Foo<[![CDATA test ]]]]>]]>', stream_get_contents($stream, -1, 0)); + } + + public function testComment() + { + $dom = $this->html5->loadHTML(' + + +
      + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('div'); + $r->comment($list->item(0)->childNodes->item(0)); + $this->assertEquals('', stream_get_contents($stream, -1, 0)); + + $dom = $this->html5->loadHTML(' + + +
      + + '); + $dom->getElementById('foo')->appendChild(new \DOMComment(' --> Foo -->')); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('div'); + $r->comment($list->item(0)->childNodes->item(0)); + + // Could not find more definitive guidelines on what this should be. Went with + // what the HTML5 spec says and what \DOMDocument::saveXML() produces. + $this->assertEquals(' --> Foo -->-->', stream_get_contents($stream, -1, 0)); + } + + public function testText() + { + $dom = $this->html5->loadHTML(' + + + + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('script'); + $r->text($list->item(0)->childNodes->item(0)); + $this->assertEquals('baz();', stream_get_contents($stream, -1, 0)); + + $dom = $this->html5->loadHTML(' + + + '); + $foo = $dom->getElementById('foo'); + $foo->appendChild(new \DOMText('')); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $r->text($foo->firstChild); + $this->assertEquals('<script>alert("hi");</script>', stream_get_contents($stream, -1, 0)); + } + + public function testNl() + { + list($o, $s) = $this->getOutputRules(); + + $m = $this->getProtectedMethod('nl'); + $m->invoke($o); + $this->assertEquals(PHP_EOL, stream_get_contents($s, -1, 0)); + } + + public function testWr() + { + list($o, $s) = $this->getOutputRules(); + + $m = $this->getProtectedMethod('wr'); + $m->invoke($o, 'foo'); + $this->assertEquals('foo', stream_get_contents($s, -1, 0)); + } + + public function getEncData() + { + return array( + array( + false, + '&\'<>"', + '&\'<>"', + '&'<>"', + ), + array( + false, + 'This + is. a < test', + 'This + is. a < test', + 'This + is. a < test', + ), + array( + false, + '.+#', + '.+#', + '.+#', + ), + + array( + true, + '.+#\'', + '.+#\'', + '.+#'', + ), + array( + true, + '&".<', + '&".<', + '&".<', + ), + array( + true, + '&\'<>"', + '&\'<>"', + '&'<>"', + ), + array( + true, + "\xc2\xa0\"'", + ' "\'', + ' "'', + ), + ); + } + + /** + * Test basic encoding of text. + * + * @dataProvider getEncData + */ + public function testEnc($isAttribute, $test, $expected, $expectedEncoded) + { + list($o, $s) = $this->getOutputRules(); + $m = $this->getProtectedMethod('enc'); + + $this->assertEquals($expected, $m->invoke($o, $test, $isAttribute)); + + list($o, $s) = $this->getOutputRules(array( + 'encode_entities' => true, + )); + $m = $this->getProtectedMethod('enc'); + $this->assertEquals($expectedEncoded, $m->invoke($o, $test, $isAttribute)); + } + + /** + * Test basic encoding of text. + * + * @dataProvider getEncData + */ + public function testEscape($isAttribute, $test, $expected, $expectedEncoded) + { + list($o, $s) = $this->getOutputRules(); + $m = $this->getProtectedMethod('escape'); + + $this->assertEquals($expected, $m->invoke($o, $test, $isAttribute)); + } + + public function booleanAttributes() + { + return array( + array(''), + array(''), + array(''), + array(''), + array(''), + array(''), + array('
      '), + array(''), + array('
      '), + array(''), + ); + } + + /** + * @dataProvider booleanAttributes + */ + public function testBooleanAttrs($html) + { + $dom = $this->html5->loadHTML('' . $html . ''); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $node = $dom->getElementsByTagName('body')->item(0)->firstChild; + + $m = $this->getProtectedMethod('attrs'); + $m->invoke($r, $node); + + $content = stream_get_contents($stream, -1, 0); + + $html = preg_replace('~<[a-z]+(.*)>~', '\1', $html); + $html = preg_replace('~<[a-z]+(.*)/?>~', '\1', $html); + + $this->assertEquals($content, $html); + } + + public function testAttrs() + { + $dom = $this->html5->loadHTML(' + + +
      foo bar baz
      + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('div'); + + $m = $this->getProtectedMethod('attrs'); + $m->invoke($r, $list->item(0)); + + $content = stream_get_contents($stream, -1, 0); + $this->assertEquals(' id="foo" class="bar baz"', $content); + } + + public function testSvg() + { + $dom = $this->html5->loadHTML( + ' + + +
      foo bar baz
      + + + + + + + + + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('svg'); + $r->element($list->item(0)); + $contents = stream_get_contents($stream, -1, 0); + $this->assertRegExp('||', $contents); + $this->assertRegExp('||', $contents); + $this->assertRegExp('||', $contents); + } + + public function testMath() + { + $dom = $this->html5->loadHTML( + ' + + +
      foo bar baz
      + + x + + ± + + y + + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('math'); + $r->element($list->item(0)); + $content = stream_get_contents($stream, -1, 0); + $this->assertRegExp('||', $content); + $this->assertRegExp('||', $content); + } + + public function testProcessorInstruction() + { + $dom = $this->html5->loadHTMLFragment(''); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $r->processorInstruction($dom->firstChild); + $content = stream_get_contents($stream, -1, 0); + $this->assertRegExp('|<\?foo bar \?>|', $content); + } + + public function testAddressTag() + { + $dom = $this->html5->loadHTML( + ' + + +
      + Dave Raggett, + Arnaud Le Hors, + contact persons for the W3C HTML Activity +
      + + '); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + + $list = $dom->getElementsByTagName('address'); + $r->element($list->item(0)); + $contents = stream_get_contents($stream, -1, 0); + + $this->assertRegExp('|
      |', $contents); + $this->assertRegExp('|Dave Raggett,|', $contents); + $this->assertRegExp('|Arnaud Le Hors,|', $contents); + $this->assertRegExp('|contact persons for the W3C HTML Activity|', $contents); + $this->assertRegExp('|
      |', $contents); + } + + /** + * Ensure direct DOM manipulation doesn't break TEXT_RAW elements (iframe, script, etc...). + */ + public function testHandlingInvalidRawContent() + { + $dom = $this->html5->loadHTML( + ' + + + + +'); + + $badNode = $dom->createElement('p', 'Bar'); + + // modify the content of the TEXT_RAW element: ')); + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Serializer/TraverserTest.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Serializer/TraverserTest.php new file mode 100644 index 000000000..d4ae7b351 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/Serializer/TraverserTest.php @@ -0,0 +1,136 @@ + + + + + Test + + +

      This is a test.

      + + '; + + public function setUp() + { + $this->html5 = $this->getInstance(); + } + + /** + * Using reflection we make a protected method accessible for testing. + * + * @param string $name + * The name of the method on the Traverser class to test + * + * @return \ReflectionMethod \ReflectionMethod for the specified method + */ + public function getProtectedMethod($name) + { + $class = new \ReflectionClass('\Masterminds\HTML5\Serializer\Traverser'); + $method = $class->getMethod($name); + $method->setAccessible(true); + + return $method; + } + + public function getTraverser() + { + $stream = fopen('php://temp', 'w'); + + $dom = $this->html5->loadHTML($this->markup); + $t = new Traverser($dom, $stream, $html5->getOptions()); + + // We return both the traverser and stream so we can pull from it. + return array( + $t, + $stream, + ); + } + + public function testConstruct() + { + // The traverser needs a place to write the output to. In our case we + // use a stream in temp space. + $stream = fopen('php://temp', 'w'); + + $html5 = $this->getInstance(); + + $r = new OutputRules($stream, $this->html5->getOptions()); + $dom = $this->html5->loadHTML($this->markup); + + $t = new Traverser($dom, $stream, $r, $html5->getOptions()); + + $this->assertInstanceOf('\Masterminds\HTML5\Serializer\Traverser', $t); + } + + public function testFragmentDeprecated() + { + $html = 'foo
      bar
      '; + $input = new \Masterminds\HTML5\Parser\StringInputStream($html); + $dom = $this->html5->parseFragment($input); + + $this->assertInstanceOf('\DOMDocumentFragment', $dom); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + $t->walk(); + + $this->assertEquals($html, stream_get_contents($stream, -1, 0)); + } + + public function testFragment() + { + $html = 'foo
      bar
      '; + $dom = $this->html5->parseFragment($html); + + $this->assertInstanceOf('\DOMDocumentFragment', $dom); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + $t->walk(); + + $this->assertEquals($html, stream_get_contents($stream, -1, 0)); + } + + public function testProcessorInstructionDeprecated() + { + $html = ''; + $input = new \Masterminds\HTML5\Parser\StringInputStream($html); + $dom = $this->html5->parseFragment($input); + + $this->assertInstanceOf('\DOMDocumentFragment', $dom); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + $t->walk(); + + $this->assertEquals($html, stream_get_contents($stream, -1, 0)); + } + + public function testProcessorInstruction() + { + $html = ''; + $dom = $this->html5->parseFragment($html); + + $this->assertInstanceOf('\DOMDocumentFragment', $dom); + + $stream = fopen('php://temp', 'w'); + $r = new OutputRules($stream, $this->html5->getOptions()); + + $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); + $t->walk(); + + $this->assertEquals($html, stream_get_contents($stream, -1, 0)); + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/HTML5/TestCase.php b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/TestCase.php new file mode 100644 index 000000000..a25ae215c --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/HTML5/TestCase.php @@ -0,0 +1,23 @@ +test'; + + const DOC_CLOSE = ''; + + public function getInstance(array $options = array()) + { + return new HTML5($options); + } + + protected function wrap($fragment) + { + return self::DOC_OPEN . $fragment . self::DOC_CLOSE; + } +} diff --git a/plugins/af_readability/vendor/masterminds/html5/test/benchmark/example.html b/plugins/af_readability/vendor/masterminds/html5/test/benchmark/example.html new file mode 100644 index 000000000..3e1bed030 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/benchmark/example.html @@ -0,0 +1,6403 @@ + + + + + + + + The New York Times - Breaking News, World News & Multimedia + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + +
      +
      + + + + +
      +
      + + + + + + + + + +
      +
      + + + +
      +
      + + +
      +
      +
      + +
      +
      +
      + +

      Hundreds of Towns in Harvey’s Path Hit by Devastating Rain

      + + + +

      • Harvey, downgraded to a tropical depression, moved to the east and punished a region of roughly 11 million people. +
      • +
      • In Houston, after the first night of a citywide curfew, many residents went outside for the first time in days to survey the wreckage. Officials have reported at least 38 deaths. +
      • +

      + + +
      +
      +
      + +
      +
      + + +
      +
      +
      +
      +
      +
      + + + + + + + +
      + +
      + + + + + + + + + + + + + + + + + +
      + + +
      + +
      +

      12 a.m. Monday

      +
      +
      +

      BEAUMONT

      +
      +
      +

      PORT

      +

      ARTHUR

      +
      +
      +

      HOUSTON

      +
      +
      +

      GULF OF

      +

      MEXICO

      +
      +
      +

      Rescue request

      +
      +
      +

      10 miles

      +
      +
      + +
      + + + + + +
      + +
      +
      + + +
      +
      +
      + +

      ‘Running Out of Time’

      + + +

      As Houston was overcome by floodwaters, thousands of people cried out for help online.

      + + +
      +
      +
      +
      +
      +
      +
      +
      + + +
      +
      +
      + +
      + +
      +
      +
      +
      + +
      + +
      + +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      To Our Readers
      +

      The Times is providing free digital access to coverage of the storm.

      +
      +
      +
      + +
      +
      + +
      + + +
      +
      + +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      + +
      + +
      + +
      +

      Top News

      + + + + +
      + +
      + +
      + +
      + + +
      +
      + +
      +
      + +
      +
      + +
      +
      + +
      + +
      + +
      +
      +
      + + + + +
      +
      +
      +

      Got a confidential news tip?

      +

      The New York Times offers several ways to get in touch with and provide materials to our journalists. Learn more.

      +
      +
      +
      + + +
      + +
      + +
      + +
      + + + +
      + +
      + +
      +
      +
      +
      + +
      +
      + +
      +
      + + +
      + + +
      +
      + + + + + + +
      +
      +
      + +
      + +

      5 Flight Safety Videos Worth Watching

      + +
      + +
      + + + +

      + A new British Airways video featuring some of the country’s best-known actors and comedians is the latest in a long line of entertaining flight safety films.

      + + +
      +
      + + + + + + +
      +
      + +

      Get a weekly roundup of the best advice from The Times on living a better, smarter, more fulfilling life.

      +
      + +
      + +
      +
      + + + +
      + +
      +
      + +
      +
      +
      + +

      David Tang, Fashion Retailer and Raconteur, Dies at 63

      + +
      + +
      + + + +

      + A lifelong entrepreneur from a wealthy family, he founded a succession of businesses catering to the affluent but also backed democracy for Hong Kong.

      + + +
      +
      +
      +
      +
      +
      +

      + Video by DENNIS OVERBYE, JONATHAN CORUM and JASON DRAKEFORD

      +
      +
      +

      Long after they have stopped communicating with Earth, the twin Voyager spacecraft will forever drift among the stars.

      +
      +
      +
      + +
      +
      + + + +
      + +
      + +

      Lawyers Under Scrutiny for Family Court Facebook Posts

      + +
      + +
      + + + +

      + Lawyers who worked for the Legal Aid Society and the city’s child welfare agency are under review for social media posts that mocked people in Family Court in Queens.

      + + +
      +
      +
      + + + + + +
      +
      +
      + +
      +
      +

      Morning Briefing: Australia Edition

      +

      The news and stories that matter to readers in Australia. Sign up to get it by email, Monday through Friday.

      + +
      +
      +
      + + + +
      + + + + +
      +
      +
      + +
      +
      +

      Morning Briefing: Asia Edition

      +

      The news and stories that matter to readers in Asia. Sign up to get it by email, Monday through Friday.

      + +
      +
      +
      + + + + +
      + + + + + +
      +
      +
      + +
      +
      +

      Morning Briefing: Europe Edition

      +

      The news and stories that matter to readers in Europe. Sign up to get it by email, Monday through Friday.

      +
      +
      +
      + + + +
      + + + + +
      +
      +
      + +
      +
      +

      California Today

      +

      The news and stories that matter to Californians, delivered weekday mornings.

      + + +
      +
      +
      + + +
      + +
      +
      +
      + +
      +
      +

      Morning Briefing

      +

      The news and stories that matter. Delivered to your inbox Monday through Friday.

      + + +
      +
      +
      + + +
      + +
      + +
      + + +
      + +
      + +
      +
      + + + + + +
      +
      +
      + +
      +

      +

      +
      + +
      +
      + +
      +
      + +
      +
      +
      +
      + +
      +
      +
      +

      +

      +
      + +
      +
      +
      + +
      + +
      + +
      +
      +
      +

      + 36 Hours in Glasgow +

      +

      + This historic city, known for its Art Nouveau flourishes, also has a blossoming modern side, with daring new buildings and bars.

      +
      +
      +
      + +
      +
      +
      + +
      + +
      + +
      + + + +
      + + +
      + +
      + +
      + +
      + +
      + +
      +
      +
      +
      + +

      What Trump Meant to Say

      + +
      + +
      + + + +

      + The president’s rogue-cop routine has serious foreign policy consequences.

      + + +
      + +
      + +
      + +
      +
      +
      + +
      +
      +
      +
      + +

      Risky Nuclear Buildup

      + +
      + +
      + + + +

      + It’s not just North Korea. Plans to upgrade America’s nuclear arsenal are also contributing to global instability.

      + + +
      + +
      + +
      +
      + +
      + +
      +
      +
      +
      + +
      + +
      + +

      User Subscriptions

      + + + +
      + +
      + +
      + +
      + +
      + + + +
      + +
      + + + + +
      +
      +
      +

      Watching

      +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      + + +
      + +
      + + +
      + +
      + +
      + + + + +
      +
      +
      +
      Loading...
      +
      + +
      +
      + +
      + +
      + + + +
      + +
      + +
      + +
      +
      +

      Sections

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + +
      + +
      + + +
      +
      +
      +
      + +
      +

      + Real Estate » +

      + + +
      + + +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      + + +
      + + +
      +
      +
      +
      +
      +
      + + + +
      +
      Loading...
      +
      +
      + + + + +
      + +
      + + + + +
      + +
      +
      +

      Go to Home Page »

      +

      + Site Index + + The New York Times + +

      + +
      + + + +
      + + +
      +
      + + + + + + + + + + + + + + + diff --git a/plugins/af_readability/vendor/masterminds/html5/test/benchmark/run.php b/plugins/af_readability/vendor/masterminds/html5/test/benchmark/run.php new file mode 100644 index 000000000..2ca190783 --- /dev/null +++ b/plugins/af_readability/vendor/masterminds/html5/test/benchmark/run.php @@ -0,0 +1,29 @@ +loadHTML($content); + +$samples = array(); +for ($i = 0; $i < $iterations; ++$i) { + $t = microtime(true); + $dom = $html5->loadHTML($content); + $samples[] = microtime(true) - $t; +} +$time = array_sum($samples) / count($samples); +echo 'Loading: ' . ($time * 1000) . "\n"; + +$samples = array(); +for ($i = 0; $i < $iterations; ++$i) { + $t = microtime(true); + $html5->saveHTML($dom); + $samples[] = microtime(true) - $t; +} +$time = array_sum($samples) / count($samples); +echo 'Writing: ' . ($time * 1000) . "\n"; + +exit(0); -- cgit v1.2.3