Merge "Unbreak the DB updater by removing transaction from doUpdates()"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 22 Jul 2016 22:03:11 +0000 (22:03 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 22 Jul 2016 22:03:11 +0000 (22:03 +0000)
340 files changed:
RELEASE-NOTES-1.28
autoload.php
composer.json
docs/distributors.txt
docs/extension.schema.json
docs/extension.schema.v1.json [new file with mode: 0644]
docs/hooks.txt
img_auth.php
includes/Category.php
includes/CategoryViewer.php
includes/DefaultSettings.php
includes/DummyLinker.php
includes/EditPage.php
includes/FileDeleteForm.php
includes/Html.php
includes/HttpFunctions.php
includes/Linker.php
includes/OutputPage.php
includes/Pingback.php [new file with mode: 0644]
includes/Revision.php
includes/Sanitizer.php
includes/ServiceWiring.php
includes/Setup.php
includes/SiteConfiguration.php
includes/StreamFile.php
includes/Title.php
includes/WatchedItemStore.php
includes/WebRequest.php
includes/WebResponse.php
includes/api/ApiLogin.php
includes/api/ApiMain.php
includes/api/ApiPurge.php
includes/api/ApiQuery.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiUpload.php
includes/api/i18n/azb.json [new file with mode: 0644]
includes/api/i18n/be-tarask.json
includes/api/i18n/ca.json
includes/api/i18n/cs.json
includes/api/i18n/de.json
includes/api/i18n/diq.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/eu.json
includes/api/i18n/fa.json
includes/api/i18n/fr.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/ja.json
includes/api/i18n/ko.json
includes/api/i18n/ksh.json
includes/api/i18n/ku-latn.json
includes/api/i18n/ps.json
includes/api/i18n/uk.json
includes/api/i18n/zh-hans.json
includes/auth/AuthManager.php
includes/auth/AuthManagerAuthPlugin.php
includes/changes/EnhancedChangesList.php
includes/collation/IcuCollation.php
includes/content/WikitextContentHandler.php
includes/db/Database.php
includes/db/DatabaseMysqlBase.php
includes/db/IDatabase.php
includes/db/loadbalancer/LBFactory.php
includes/db/loadbalancer/LoadBalancer.php
includes/deferred/AtomicSectionUpdate.php
includes/deferred/AutoCommitUpdate.php [new file with mode: 0644]
includes/deferred/LinksDeletionUpdate.php
includes/deferred/LinksUpdate.php
includes/deferred/SiteStatsUpdate.php
includes/diff/DifferenceEngine.php
includes/exception/MWExceptionHandler.php
includes/export/DumpStringOutput.php [new file with mode: 0644]
includes/filebackend/FileBackend.php
includes/filebackend/FileBackendStore.php
includes/filebackend/MemoryFileBackend.php
includes/filebackend/SwiftFileBackend.php
includes/filerepo/FileRepo.php
includes/filerepo/file/LocalFile.php
includes/gallery/ImageGalleryBase.php
includes/gallery/SliderImageGallery.php [deleted file]
includes/gallery/SlideshowImageGallery.php [new file with mode: 0644]
includes/gallery/TraditionalImageGallery.php
includes/htmlform/HTMLCheckField.php
includes/htmlform/HTMLCheckMatrix.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/HTMLMultiSelectField.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.php
includes/installer/LocalSettingsGenerator.php
includes/installer/WebInstallerName.php
includes/installer/WebInstallerOutput.php
includes/installer/i18n/be-tarask.json
includes/installer/i18n/bn.json
includes/installer/i18n/de.json
includes/installer/i18n/en.json
includes/installer/i18n/et.json
includes/installer/i18n/fi.json
includes/installer/i18n/fr.json
includes/installer/i18n/gl.json
includes/installer/i18n/he.json
includes/installer/i18n/ja.json
includes/installer/i18n/ko.json
includes/installer/i18n/ksh.json
includes/installer/i18n/pl.json
includes/installer/i18n/qqq.json
includes/installer/i18n/ru.json
includes/installer/i18n/tcy.json
includes/installer/i18n/wuu.json
includes/installer/i18n/zh-hans.json
includes/installer/i18n/zh-hant.json
includes/jobqueue/jobs/DeleteLinksJob.php
includes/jobqueue/jobs/RefreshLinksJob.php
includes/libs/MultiHttpClient.php
includes/libs/ReverseArrayIterator.php [new file with mode: 0644]
includes/libs/objectcache/RESTBagOStuff.php
includes/linker/LinkRenderer.php
includes/linker/LinkRendererFactory.php
includes/media/MediaTransformOutput.php
includes/page/WikiPage.php
includes/parser/LinkHolderArray.php
includes/parser/MWTidy.php
includes/parser/Parser.php
includes/parser/Preprocessor_Hash.php
includes/profiler/ProfilerStub.php
includes/registration/ExtensionProcessor.php
includes/registration/ExtensionRegistry.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderSiteStylesModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevDelArchivedFileItem.php
includes/revisiondelete/RevDelFileItem.php
includes/revisiondelete/RevDelList.php
includes/search/SearchIndexField.php
includes/skins/BaseTemplate.php
includes/skins/Skin.php
includes/skins/SkinTemplate.php
includes/specials/SpecialBlock.php
includes/specials/SpecialCreateAccount.php
includes/specials/SpecialLog.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialTrackingCategories.php
includes/specials/SpecialUserLogin.php
includes/specials/pagers/ContribsPager.php
includes/specials/pre-authmanager/SpecialUserlogin.php
includes/tidy/Balancer.php [new file with mode: 0644]
includes/tidy/Html5Internal.php [new file with mode: 0644]
includes/tidy/RaggettWrapper.php
includes/upload/UploadBase.php
includes/user/User.php
includes/utils/BatchRowIterator.php
languages/Language.php
languages/classes/LanguageEo.php [deleted file]
languages/data/Names.php
languages/data/ZhConversion.php
languages/i18n/aeb-arab.json
languages/i18n/af.json
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dty.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frp.json
languages/i18n/gl.json
languages/i18n/got.json
languages/i18n/hak.json
languages/i18n/he.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/ia.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/khw.json
languages/i18n/ko.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/lb.json
languages/i18n/lij.json
languages/i18n/lki.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/mk.json
languages/i18n/mr.json
languages/i18n/ms.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nds-nl.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/olo.json
languages/i18n/or.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/ta.json
languages/i18n/tcy.json
languages/i18n/tr.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/vi.json
languages/i18n/wuu.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesPs.php
maintenance/cleanupEmptyCategories.php [new file with mode: 0644]
maintenance/deleteArchivedFiles.php
maintenance/jsduck/categories.json
maintenance/language/zhtable/simp2trad.manual
maintenance/language/zhtable/simp2trad_noconvert.manual
maintenance/language/zhtable/toCN.manual
maintenance/language/zhtable/toHK.manual
maintenance/language/zhtable/toSimp.manual
maintenance/language/zhtable/toTW.manual
maintenance/language/zhtable/toTrad.manual
maintenance/language/zhtable/trad2simp_noconvert.manual
maintenance/language/zhtable/tradphrases.manual
maintenance/language/zhtable/tradphrases_exclude.manual
maintenance/mssql/tables.sql
maintenance/rebuildFileCache.php
maintenance/tables.sql
maintenance/updateExtensionJsonSchema.php [new file with mode: 0644]
package.json
resources/Resources.php
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-core-apex.css
resources/lib/oojs-ui/oojs-ui-core-mediawiki.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css
resources/lib/oojs-ui/oojs-ui-toolbars.js
resources/lib/oojs-ui/oojs-ui-widgets-apex.css
resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/themes/apex/images/icons/flag-rtl.png
resources/lib/oojs-ui/themes/apex/images/icons/flag-rtl.svg
resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.png
resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.svg
resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.png
resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stop-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/stop-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stop.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/stop.svg
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.skinning/content.css
resources/src/mediawiki.skinning/images/external link icons.svg [deleted file]
resources/src/mediawiki.skinning/images/external-link-icons.svg [new file with mode: 0644]
resources/src/mediawiki.special/mediawiki.special.changeslist.css
resources/src/mediawiki.toolbar/toolbar.less
resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js
resources/src/mediawiki/api/messages.js
resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
resources/src/mediawiki/mediawiki.content.json.css [deleted file]
resources/src/mediawiki/mediawiki.content.json.less [new file with mode: 0644]
resources/src/mediawiki/mediawiki.raggett.css
resources/src/mediawiki/page/gallery-slider.js [deleted file]
resources/src/mediawiki/page/gallery-slideshow.js [new file with mode: 0644]
resources/src/mediawiki/page/gallery.css
resources/src/mediawiki/page/startup.js
tests/parser/parserTest.inc
tests/parser/parserTests.txt
tests/parserTests.php
tests/phpunit/includes/ExportTest.php
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php
tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/HttpTest.php
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/MWNamespaceTest.php
tests/phpunit/includes/MWTimestampTest.php
tests/phpunit/includes/RevisionStorageTest.php
tests/phpunit/includes/SanitizerTest.php
tests/phpunit/includes/WatchedItemStoreUnitTest.php
tests/phpunit/includes/changes/RCCacheEntryFactoryTest.php
tests/phpunit/includes/changes/TestRecentChangesHelper.php
tests/phpunit/includes/content/CssContentTest.php
tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
tests/phpunit/includes/filebackend/FileBackendTest.php
tests/phpunit/includes/installer/DatabaseUpdaterTest.php
tests/phpunit/includes/libs/XmlTypeCheckTest.php
tests/phpunit/includes/linker/LinkRendererFactoryTest.php
tests/phpunit/includes/linker/LinkRendererTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/registration/CoreVersionCheckerTest.php
tests/phpunit/includes/registration/ExtensionProcessorTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/includes/tidy/BalancerTest.php [new file with mode: 0644]
tests/phpunit/includes/tidy/html5lib-tests.json [new file with mode: 0644]
tests/phpunit/includes/title/MediaWikiTitleCodecTest.php
tests/testHelpers.inc

index 6976655..a20bec0 100644 (file)
@@ -6,6 +6,9 @@ MediaWiki 1.28 is an alpha-quality branch and is not recommended for use in
 production.
 
 === Configuration changes in 1.28 ===
+* BREAKING CHANGE: $wgHTTPProxy is now *required* for all external requests
+  made by MediaWiki via a proxy. Relying on the http_proxy environment
+  variable is no longer supported.
 * The load.php entry point now enforces the existing policy of not allowing
   access to session data, which includes the session user and the session
   user's language. If such access is attempted, an exception will be thrown.
@@ -16,10 +19,17 @@ production.
 * $wgForeignUploadTargets now defaults to `[ 'local' ]`, where `'local'`
   signifies local uploads. A value of `[]` (empty array) now means that
   no upload targets are allowed, effectively disabling the upload dialog.
+* The deprecated $wgEditEncoding variable has been removed; it was only used
+  for Esperanto language character conversion. You are now recommended to use
+  input methods provided by the UniversalLanguageSelector extension.
+* When $wgPingback is true, MediaWiki will periodically ping
+  https://www.mediawiki.org/beacon with basic information about the local
+  MediaWiki installation.  This data includes, for example, the type of system,
+  PHP version, and chosen database backend. This behavior is off by default.
 
 === New features in 1.28 ===
 * User::isBot() method for checking if an account is a bot role account.
-* Added a new 'slider' mode for galleries.
+* Added a new 'slideshow' mode for galleries.
 * Added a new hook, 'UserIsBot', to aid in determining if a user is a bot.
 * Added a new hook, 'ApiMakeParserOptions', to allow extensions to better
   interact with API parsing.
@@ -52,6 +62,8 @@ changes to languages because of Phabricator reports.
 
 * (T137411) ban (Balinese), thanks to translators Adi Mayndra, Andru,
   BASAbali, M. Adiputra, Naval Scene, Nemo bis, NoiX180, and 아라.
+* (T135867) shn (Shan), thanks to translators Khun Sar, Piangpha,
+  Saiddzone Saimawnkham, Saosukham, and Sengwan.
 
 === Other changes in 1.28 ===
 * (T128697) Improved handling of large diffs.
@@ -59,6 +71,10 @@ changes to languages because of Phabricator reports.
   use or update a custom session provider if needed.
 * Deprecated APIEditBeforeSave hook in favor of EditFilterMergedContent.
 * The 'UploadVerification' hook is deprecated. Use 'UploadVerifyFile' instead.
+* SiteConfiguration::isLocalVHost() was removed (deprecated since 1.25).
+* The 'UserLoginComplete' hook has a new parameter to differentiate between actual
+  login and visiting the login page while already logged in.
+* ResourceLoader::makeLoaderURL() was removed (deprecated since 1.24).
 
 == Compatibility ==
 
index 8ff7771..17b34e5 100644 (file)
@@ -157,6 +157,7 @@ $wgAutoloadLocalClasses = [
        'AuthManagerSpecialPage' => __DIR__ . '/includes/specialpage/AuthManagerSpecialPage.php',
        'AuthPlugin' => __DIR__ . '/includes/AuthPlugin.php',
        'AuthPluginUser' => __DIR__ . '/includes/AuthPlugin.php',
+       'AutoCommitUpdate' => __DIR__ . '/includes/deferred/AutoCommitUpdate.php',
        'AutoLoader' => __DIR__ . '/includes/AutoLoader.php',
        'AutoloadGenerator' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
        'Autopromote' => __DIR__ . '/includes/Autopromote.php',
@@ -245,6 +246,7 @@ $wgAutoloadLocalClasses = [
        'ClassCollector' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
        'CleanupAncientTables' => __DIR__ . '/maintenance/cleanupAncientTables.php',
        'CleanupBlocks' => __DIR__ . '/maintenance/cleanupBlocks.php',
+       'CleanupEmptyCategories' => __DIR__ . '/maintenance/cleanupEmptyCategories.php',
        'CleanupPreferences' => __DIR__ . '/maintenance/cleanupPreferences.php',
        'CleanupRemovedModules' => __DIR__ . '/maintenance/cleanupRemovedModules.php',
        'CleanupSpam' => __DIR__ . '/maintenance/cleanupSpam.php',
@@ -389,6 +391,7 @@ $wgAutoloadLocalClasses = [
        'DumpPipeOutput' => __DIR__ . '/includes/export/DumpPipeOutput.php',
        'DumpRenderer' => __DIR__ . '/maintenance/renderDump.php',
        'DumpRev' => __DIR__ . '/maintenance/storage/dumpRev.php',
+       'DumpStringOutput' => __DIR__ . '/includes/export/DumpStringOutput.php',
        'DuplicateJob' => __DIR__ . '/includes/jobqueue/jobs/DuplicateJob.php',
        'EditAction' => __DIR__ . '/includes/actions/EditAction.php',
        'EditCLI' => __DIR__ . '/maintenance/edit.php',
@@ -663,7 +666,6 @@ $wgAutoloadLocalClasses = [
        'LanguageConverter' => __DIR__ . '/languages/LanguageConverter.php',
        'LanguageCu' => __DIR__ . '/languages/classes/LanguageCu.php',
        'LanguageDsb' => __DIR__ . '/languages/classes/LanguageDsb.php',
-       'LanguageEo' => __DIR__ . '/languages/classes/LanguageEo.php',
        'LanguageEs' => __DIR__ . '/languages/classes/LanguageEs.php',
        'LanguageEt' => __DIR__ . '/languages/classes/LanguageEt.php',
        'LanguageFi' => __DIR__ . '/languages/classes/LanguageFi.php',
@@ -879,7 +881,14 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Session\\Token' => __DIR__ . '/includes/session/Token.php',
        'MediaWiki\\Session\\UserInfo' => __DIR__ . '/includes/session/UserInfo.php',
        'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
+       'MediaWiki\\Tidy\\BalanceActiveFormattingElements' => __DIR__ . '/includes/tidy/Balancer.php',
+       'MediaWiki\\Tidy\\BalanceElement' => __DIR__ . '/includes/tidy/Balancer.php',
+       'MediaWiki\\Tidy\\BalanceMarker' => __DIR__ . '/includes/tidy/Balancer.php',
+       'MediaWiki\\Tidy\\BalanceSets' => __DIR__ . '/includes/tidy/Balancer.php',
+       'MediaWiki\\Tidy\\BalanceStack' => __DIR__ . '/includes/tidy/Balancer.php',
+       'MediaWiki\\Tidy\\Balancer' => __DIR__ . '/includes/tidy/Balancer.php',
        'MediaWiki\\Tidy\\Html5Depurate' => __DIR__ . '/includes/tidy/Html5Depurate.php',
+       'MediaWiki\\Tidy\\Html5Internal' => __DIR__ . '/includes/tidy/Html5Internal.php',
        'MediaWiki\\Tidy\\RaggettBase' => __DIR__ . '/includes/tidy/RaggettBase.php',
        'MediaWiki\\Tidy\\RaggettExternal' => __DIR__ . '/includes/tidy/RaggettExternal.php',
        'MediaWiki\\Tidy\\RaggettInternalHHVM' => __DIR__ . '/includes/tidy/RaggettInternalHHVM.php',
@@ -978,7 +987,6 @@ $wgAutoloadLocalClasses = [
        'PNGMetadataExtractor' => __DIR__ . '/includes/media/PNGMetadataExtractor.php',
        'PPCustomFrame_DOM' => __DIR__ . '/includes/parser/Preprocessor_DOM.php',
        'PPCustomFrame_Hash' => __DIR__ . '/includes/parser/Preprocessor_Hash.php',
-       'PPDAccum_Hash' => __DIR__ . '/includes/parser/Preprocessor_Hash.php',
        'PPDPart' => __DIR__ . '/includes/parser/Preprocessor_DOM.php',
        'PPDPart_Hash' => __DIR__ . '/includes/parser/Preprocessor_Hash.php',
        'PPDStack' => __DIR__ . '/includes/parser/Preprocessor_DOM.php',
@@ -1030,6 +1038,7 @@ $wgAutoloadLocalClasses = [
        'PermissionsError' => __DIR__ . '/includes/exception/PermissionsError.php',
        'PhpHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
        'PhpXmlBugTester' => __DIR__ . '/includes/installer/PhpBugTests.php',
+       'Pingback' => __DIR__ . '/includes/Pingback.php',
        'PoolCounter' => __DIR__ . '/includes/poolcounter/PoolCounter.php',
        'PoolCounterRedis' => __DIR__ . '/includes/poolcounter/PoolCounterRedis.php',
        'PoolCounterWork' => __DIR__ . '/includes/poolcounter/PoolCounterWork.php',
@@ -1176,6 +1185,7 @@ $wgAutoloadLocalClasses = [
        'RevDelLogList' => __DIR__ . '/includes/revisiondelete/RevDelLogList.php',
        'RevDelRevisionItem' => __DIR__ . '/includes/revisiondelete/RevDelRevisionItem.php',
        'RevDelRevisionList' => __DIR__ . '/includes/revisiondelete/RevDelRevisionList.php',
+       'ReverseArrayIterator' => __DIR__ . '/includes/libs/ReverseArrayIterator.php',
        'ReverseChronologicalPager' => __DIR__ . '/includes/pager/ReverseChronologicalPager.php',
        'RevertAction' => __DIR__ . '/includes/actions/RevertAction.php',
        'Revision' => __DIR__ . '/includes/Revision.php',
@@ -1251,7 +1261,7 @@ $wgAutoloadLocalClasses = [
        'SkinFallback' => __DIR__ . '/includes/skins/SkinFallback.php',
        'SkinFallbackTemplate' => __DIR__ . '/includes/skins/SkinFallbackTemplate.php',
        'SkinTemplate' => __DIR__ . '/includes/skins/SkinTemplate.php',
-       'SliderImageGallery' => __DIR__ . '/includes/gallery/SliderImageGallery.php',
+       'SlideshowImageGallery' => __DIR__ . '/includes/gallery/SlideshowImageGallery.php',
        'SpecialActiveUsers' => __DIR__ . '/includes/specials/SpecialActiveusers.php',
        'SpecialAllMessages' => __DIR__ . '/includes/specials/SpecialAllMessages.php',
        'SpecialAllMyUploads' => __DIR__ . '/includes/specials/SpecialMyRedirectPages.php',
@@ -1430,6 +1440,7 @@ $wgAutoloadLocalClasses = [
        'UpdateArticleCount' => __DIR__ . '/maintenance/updateArticleCount.php',
        'UpdateCollation' => __DIR__ . '/maintenance/updateCollation.php',
        'UpdateDoubleWidthSearch' => __DIR__ . '/maintenance/updateDoubleWidthSearch.php',
+       'UpdateExtensionJsonSchema' => __DIR__ . '/maintenance/updateExtensionJsonSchema.php',
        'UpdateLogging' => __DIR__ . '/maintenance/archives/upgradeLogging.php',
        'UpdateMediaWiki' => __DIR__ . '/maintenance/update.php',
        'UpdateRestrictions' => __DIR__ . '/maintenance/updateRestrictions.php',
index 04a5e85..54eb3c0 100644 (file)
@@ -16,7 +16,7 @@
                "wiki": "https://www.mediawiki.org/"
        },
        "require": {
-               "composer/semver": "1.4.0",
+               "composer/semver": "1.4.1",
                "cssjanus/cssjanus": "1.1.2",
                "ext-ctype": "*",
                "ext-iconv": "*",
@@ -25,7 +25,7 @@
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.17.5",
+               "oojs/oojs-ui": "0.17.6",
                "oyejorge/less.php": "1.7.0.10",
                "php": ">=5.5.9",
                "psr/log": "1.0.0",
@@ -40,7 +40,7 @@
                "wikimedia/relpath": "1.0.3",
                "wikimedia/running-stat": "1.1.0",
                "wikimedia/utfnormal": "1.0.3",
-               "wikimedia/wrappedstring": "2.1.1",
+               "wikimedia/wrappedstring": "2.2.0",
                "zordius/lightncandy": "0.23"
        },
        "require-dev": {
index efa573d..f19574c 100644 (file)
@@ -1,23 +1,23 @@
 This document is intended to provide useful advice for parties seeking to
-redistribute MediaWiki to end users.  It's targeted particularly at maintainers
+redistribute MediaWiki to end users. It's targeted particularly at maintainers
 for Linux distributions, since it's been observed that distribution packages of
-MediaWiki often break.  We've consistently had to recommend that users seeking
+MediaWiki often break. We've consistently had to recommend that users seeking
 support use official tarballs instead of their distribution's packages, and
-this often solves whatever problem the user is having.  It would be nice if
+this often solves whatever problem the user is having. It would be nice if
 this could change.
 
 == Background: why web applications are different ==
 
 MediaWiki is intended to be usable on any web host that provides support for
-PHP and a database.  Many users of low-end shared hosting have very limited
+PHP and a database. Many users of low-end shared hosting have very limited
 access to their machine: often only FTP access to some subdirectory of the web
-root.  Support for these users entails several restrictions, such as:
+root. Support for these users entails several restrictions, such as:
 
-  1) We cannot require installation of any files outside the web root.  Few of
+  1) We cannot require installation of any files outside the web root. Few of
   our users have access to directories like /usr or /etc.
   2) We cannot require the ability to run any utility on the command line.
   Many shared hosts have exec() and similar PHP functions disabled.
-  3) We cannot assume that the software has write access anywhere useful.  The
+  3) We cannot assume that the software has write access anywhere useful. The
   user account that MediaWiki (including its installer) runs under is often
   different from the account the user used to upload the files, and we might be
   restricted by PHP settings such as safe mode or open_basedir.
@@ -30,28 +30,28 @@ root.  Support for these users entails several restrictions, such as:
 
 Since anything that works on cheap shared hosting will work if you have shell
 or root access too, MediaWiki's design is based around catering to the lowest
-common denominator.  Although we support higher-end setups as well (like
+common denominator. Although we support higher-end setups as well (like
 Wikipedia!), the way many things work by default is tailored toward shared
-hosting.  These defaults are unconventional from the point of view of normal
+hosting. These defaults are unconventional from the point of view of normal
 (non-web) applications -- they might conflict with distributors' policies, and
 they certainly aren't ideal for someone who's installing MediaWiki as root.
 
 == Directory structure ==
 
 Because of constraint (1) above, MediaWiki does not conform to normal
-Unix filesystem layout.  Hopefully we'll offer direct support for standard
+Unix filesystem layout. Hopefully we'll offer direct support for standard
 layouts in the future, but for now *any change to the location of files is
-unsupported*.  Moving things and leaving symlinks will *probably* not break
+unsupported*. Moving things and leaving symlinks will *probably* not break
 anything, but it is *strongly* advised not to try any more intrusive changes to
-get MediaWiki to conform more closely to your filesystem hierarchy.  Any such
+get MediaWiki to conform more closely to your filesystem hierarchy. Any such
 attempt will almost certainly result in unnecessary bugs.
 
 The standard recommended location to install MediaWiki, relative to the web
-root, is /w (so, e.g., /var/www/w).  Rewrite rules can then be used to enable
-"pretty URLs" like /wiki/Article instead of /w/index.php?title=Article.  (This
+root, is /w (so, e.g., /var/www/w). Rewrite rules can then be used to enable
+"pretty URLs" like /wiki/Article instead of /w/index.php?title=Article. (This
 is the convention Wikipedia uses.)  In theory, it should be possible to enable
 the appropriate rewrite rules by default, if you can reconfigure the web
-server, but you'd need to alter LocalSettings.php too.  See
+server, but you'd need to alter LocalSettings.php too. See
 <https://www.mediawiki.org/wiki/Manual:Short_URL> for details on short URLs.
 
 If you really must mess around with the directory structure, note that the
@@ -59,37 +59,38 @@ following files *must* all be web-accessible for MediaWiki to function
 correctly:
 
   * api.php, img_auth.php, index.php, load.php, opensearch_desc.php, thumb.php,
-  profileinfo.php, redirect.php, trackback.php.  These are the entry points for
-  normal usage.  This list may be incomplete and is subject to change.
+  profileinfo.php. These are the entry points for normal usage. This list may be
+  incomplete and is subject to change.
   * mw-config/index.php: Used for web-based installation (sets up the database,
   prompts for the name of the wiki, etc.).
-  * images/: Used for uploaded files.  This could be somewhere else if
+  * images/: Used for uploaded files. This could be somewhere else if
   $wgUploadDirectory and $wgUploadPath are changed appropriately.
   * skins/*/: Subdirectories of skins/ contain CSS and JavaScript files that
-  must be accessible to web browsers.  The PHP files and Skin.sample in skins/
-  don't need to be accessible.  This could be somewhere else if
+  must be accessible to web browsers. The PHP files and Skin.sample in skins/
+  don't need to be accessible. This could be somewhere else if
   $wgStyleDirectory and $wgStylePath are changed appropriately.
   * extensions/: Many extensions include CSS and JavaScript files in their
-  extensions directory, and will break if they aren't web-accessible.  Some
+  extensions directory, and will break if they aren't web-accessible. Some
   extensions might theoretically provide additional entry points as well, at
   least in principle.
 
 But all files should keep their position relative to the web-visible
-installation directory no matter what.  If you must move includes/ somewhere in
-/usr/share, provide a symlink from /var/www/w.  If you don't, you *will* break
-something.  You have been warned.
+installation directory no matter what. If you must move includes/ somewhere in
+/usr/share, provide a symlink from /var/www/w. If you don't, you *will* break
+something. You have been warned.
 
 == Configuration ==
 
-MediaWiki is configured using LocalSettings.php.  This is a PHP file that's
+MediaWiki is configured using LocalSettings.php. This is a PHP file that's
 generated when the user visits mw-config/index.php to install the software, and
-which the user can edit by hand thereafter.  It's just a plain old PHP file,
-and can contain any PHP statements.  It usually sets global variables that are
+which the user can edit by hand thereafter. It's just a plain old PHP file,
+and can contain any PHP statements. It usually sets global variables that are
 used for configuration, and includes files used by any extensions.
 
-Distributors can easily add extra statements to the autogenerated
-LocalSettings.php by changing mw-config/overrides.php (see that file for details
-and examples).
+Distributors can easily change the installer behavior, including LocalSettings
+generated, by placing their overrides into mw-config/overrides directory. Doing
+that is highly preferred to modifying MediaWiki code directly. See
+mw-config/overrides/README for more details and examples.
 
 There's a new maintenance/install.php script which could be used for performing
 an install through the command line.
@@ -98,7 +99,7 @@ Some configuration options that distributors might be in a position to set
 intelligently:
 
   * $wgEmergencyContact: An e-mail address that can be used to contact the wiki
-  administrator.  By default, "wikiadmin@ServerName".
+  administrator. By default, "wikiadmin@ServerName".
   * $wgPasswordSender: The e-mail address to use when sending password e-mails.
   By default, "MediaWiki Mail <apache@ServerName>".
        (with ServerName guessed from the http request)
@@ -115,16 +116,16 @@ Any package manager which replaces the files but doesn't update the db is leavin
 an inconsistent wiki that may produce blank pages (php errors) when new features 
 using the changed schema would be used.
 
-Since MediaWiki 1.17 it is possible to upgrade using the installer by providing 
+Since MediaWiki 1.17 it is possible to upgrade using the web installer by providing
 an arbitrary secret value stored as $wgUpgradeKey in LocalSettings (older versions 
 needed to rename LocalSettings.php in order to upgrade using the installer).
 
 == Documentation ==
 
 MediaWiki's official documentation is split between two places: the source
-code, and <https://www.mediawiki.org/>.  The source code documentation is written
+code, and <https://www.mediawiki.org/>. The source code documentation is written
 exclusively by developers, and so is likely to be reliable (at worst,
-outdated).  However, it can be pretty sparse.  mediawiki.org documentation is
+outdated). However, it can be pretty sparse. mediawiki.org documentation is
 often much more thorough, but it's maintained by a wiki that's open to
 anonymous edits, so its quality is sometimes sketchy -- don't assume that
 anything there is officially endorsed!
@@ -132,31 +133,27 @@ anything there is officially endorsed!
 == Upstream ==
 
 MediaWiki is a project hosted and led by the Wikimedia Foundation, the
-not-for-profit charity that operates Wikipedia.  Wikimedia employs the lead
+not-for-profit charity that operates Wikipedia. Wikimedia employs the lead
 developer and several other paid developers, but commit access is given out
-liberally and there are multiple very active volunteer developers as well.  A
+liberally and there are multiple very active volunteer developers as well. A
 list of developers can be found at <https://www.mediawiki.org/wiki/Developers>.
 
-MediaWiki's bug tracker is at <https://bugzilla.wikimedia.org>.  However, most
-developers follow the bug tracker little or not at all.  The best place to
-post if you want to get developers' attention is the wikitech-l mailing list
-<https://lists.wikimedia.org/mailman/listinfo/wikitech-l>.  Posts to wikitech-l
-will inevitably be read by multiple experienced MediaWiki developers.  There's
+MediaWiki's bug tracker is at <https://phabricator.wikimedia.org>. However, you
+might find that the best place to post if you want to get developers' attention
+is the wikitech-l mailing list
+<https://lists.wikimedia.org/mailman/listinfo/wikitech-l>. Posts to wikitech-l
+will inevitably be read by multiple experienced MediaWiki developers. There's
 also an active IRC chat at <irc://irc.freenode.net/mediawiki>, where there are
 usually several developers at reasonably busy times of day.
 
-Unfortunately, we don't have a very good system for patch review.  Patches
-should be submitted on Bugzilla (as unified diffs produced with "svn diff"
-against the latest trunk revision), but many patches languish without review
-until they bitrot into uselessness.  You might want to get a developer to
-commit to reviewing your patch before you put too much effort into it.
-Reasonably straightforward patches shouldn't be too hard to get accepted if
-there's an interested developer, however -- posting to Bugzilla and then
-dropping a note on wikitech-l if nobody responds is a good tactic.
+Our Git repositories are hosted at <https://gerrit.wikimedia.org>, see
+<https://www.mediawiki.org/wiki/Gerrit> for more information. Patches should
+be submitted there. If you know which developers are best suited to review your
+patch, add them to it, otherwise ask on IRC to get better review time.
 
 All redistributors of MediaWiki should be subscribed to mediawiki-announce
-<https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce>.  It's
-extremely low-traffic, with an average of less than one post per month.  All
+<https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce>. It's
+extremely low-traffic, with an average of less than one post per month. All
 new releases are announced here, including critical security updates.
 
 == Useful software to install ==
@@ -167,41 +164,40 @@ perhaps configure it to use them (see Configuration section of this document):
 
   * APC (Alternative PHP Cache), XCache, or similar: Will greatly speed up the
   execution of MediaWiki, and all other PHP applications, at some cost in
-  memory usage.  Will be used automatically for the most part.
-  * clamav: Can be used for virus scanning of uploaded files.  Enable with
+  memory usage. Will be used automatically for the most part.
+  * clamav: Can be used for virus scanning of uploaded files. Enable with
   "$wgAntivirus = 'clamav';".
-  * DjVuLibre: Allows processing of DjVu files.  To enable this, set
+  * DjVuLibre: Allows processing of DjVu files. To enable this, set
   "$wgDjvuDump = 'djvudump'; $wgDjvuRenderer = 'ddjvu'; $wgDjvuTxt = 'djvutxt';".
-  * HTML Tidy: Fixes errors in HTML at runtime.  Can be enabled with 
+  * HTML Tidy: Fixes errors in HTML at runtime. Can be enabled with 
        "$wgUseTidy = true;".
-  * ImageMagick: For resizing images.  "$wgUseImageMagick = true;" will enable
-  it.  PHP's GD can also be used, but ImageMagick is preferable.
-  * Squid: Can provide a drastic speedup and a major cut in resource
-  consumption, but enabling it may interfere with other applications.  It might
-  be suitable for a separate mediawiki-squid package.  For setup details, see:
-  <https://www.mediawiki.org/wiki/Manual:Squid_caching>
+  * ImageMagick: For resizing images. "$wgUseImageMagick = true;" will enable
+  it. PHP's GD can also be used, but ImageMagick is preferable.
+  * HTTP cache such as Varnish or Squid: can provide a drastic speedup and a
+  major cut in resource consumption, but enabling it may interfere with other
+  applications. It might be suitable for a separate package. For setup details, see:
+  - <https://www.mediawiki.org/wiki/Manual:Varnish_caching>
+  - <https://www.mediawiki.org/wiki/Manual:Squid_caching>
   * rsvg or other SVG rasterizer: ImageMagick can be used for SVG support, but
-  is not ideal.  Wikipedia (as of the time of this writing) uses rsvg.  To
+  is not ideal. Wikipedia (as of the time of this writing) uses rsvg. To
   enable, set "$wgSVGConverter = 'rsvg';" (or other as appropriate).
-  * texvc: Included with MediaWiki.  Instructions for compiling and
-  installing it are in the math/ directory.
 
-MediaWiki uses some standard GNU utilities as well, such as diff and diff3.  If
+MediaWiki uses some standard GNU utilities as well, such as diff and diff3. If
 these are present in /usr/bin or some other reasonable location, they will be
 configured automatically on install.
 
-MediaWiki also has a "job queue" that handles background processing.  Because
+MediaWiki also has a "job queue" that handles background processing. Because
 shared hosts often don't provide access to cron, the job queue is run on every
-page view by default.  This means the background tasks aren't really done in
-the background.  Busy wikis can set $wgJobRunRate to 0 and run
-maintenance/runJobs.php periodically out of cron.  Distributors probably
+page view by default. This means the background tasks aren't really done in
+the background. Busy wikis can set $wgJobRunRate to 0 and run
+maintenance/runJobs.php periodically out of cron. Distributors probably
 shouldn't set this up as a default, however, since the extra cron job is
 unnecessary overhead for a little-used wiki.
 
 == Web server configuration ==
 
 MediaWiki includes several .htaccess files to restrict access to some
-directories.  If the web server is not configured to support these files, and
+directories. If the web server is not configured to support these files, and
 the relevant directories haven't been moved someplace inaccessible anyway (e.g.
 symlinked in /usr/share with the web server configured to not follow symlinks),
 then it might be useful to deny web access to those directories in the web
index 3235c95..14a9731 100644 (file)
                        ],
                        "description": "A function to be called right after MediaWiki processes this file"
                },
+               "config_prefix": {
+                       "type": "string",
+                       "default": "wg",
+                       "description": "Prefix to put in front of configuration settings when exporting them to $GLOBALS"
+               },
                "config": {
                        "type": "object",
                        "description": "Configuration options for this extension",
-                       "properties": {
-                               "_prefix": {
-                                       "type": "string",
-                                       "default": "wg",
-                                       "description": "Prefix to put in front of configuration settings when exporting them to $GLOBALS"
-                               }
-                       },
                        "patternProperties": {
                                "^[a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*$": {
                                        "properties": {
-                                               "_merge_strategy": {
+                                               "value": {
+                                                       "required": true
+                                               },
+                                               "merge_strategy": {
                                                        "type": "string",
                                                        "enum": [
                                                                "array_merge_recursive",
                                                                "array_merge"
                                                        ],
                                                        "default": "array_merge"
+                                               },
+                                               "description": {
+                                                       "type": ["string", "array"],
+                                                       "description": "A description of the config setting, mostly for documentation/developers"
                                                }
                                        }
                                }
diff --git a/docs/extension.schema.v1.json b/docs/extension.schema.v1.json
new file mode 100644 (file)
index 0000000..893facf
--- /dev/null
@@ -0,0 +1,886 @@
+{
+       "$schema": "http://json-schema.org/schema#",
+       "description": "MediaWiki extension.json schema",
+       "type": "object",
+       "properties": {
+               "manifest_version": {
+                       "type": "integer",
+                       "description": "Version of the extension.json schema the extension.json file is in.",
+                       "required": true
+               },
+               "name": {
+                       "type": "string",
+                       "description": "The extension's canonical name.",
+                       "required": true
+               },
+               "namemsg": {
+                       "type": "string",
+                       "description": "i18n message key of the extension's name."
+               },
+               "type": {
+                       "type": "string",
+                       "description": "The extension's type, as an index to $wgExtensionCredits.",
+                       "default": "other"
+               },
+               "author": {
+                       "type": [
+                               "string",
+                               "array"
+                       ],
+                       "description": "Extension's authors.",
+                       "items": {
+                               "type": "string"
+                       }
+               },
+               "version": {
+                       "type": "string",
+                       "description": "The version of this release of the extension."
+               },
+               "url": {
+                       "type": "string",
+                       "description": "URL to the homepage for the extension.",
+                       "format": "uri"
+               },
+               "description": {
+                       "type": "string",
+                       "description": "Raw description of the extension."
+               },
+               "descriptionmsg": {
+                       "type": "string",
+                       "description": "Message key for a i18n message describing the extension."
+               },
+               "license-name": {
+                       "type": "string",
+                       "description": "Short identifier for the license under which the extension is released.",
+                       "enum": [
+                               "AFL-1.1",
+                               "AFL-1.2",
+                               "AFL-2.0",
+                               "AFL-2.1",
+                               "AFL-3.0",
+                               "APL-1.0",
+                               "Aladdin",
+                               "ANTLR-PD",
+                               "Apache-1.0",
+                               "Apache-1.1",
+                               "Apache-2.0",
+                               "APSL-1.0",
+                               "APSL-1.1",
+                               "APSL-1.2",
+                               "APSL-2.0",
+                               "Artistic-1.0",
+                               "Artistic-1.0-cl8",
+                               "Artistic-1.0-Perl",
+                               "Artistic-2.0",
+                               "AAL",
+                               "BitTorrent-1.0",
+                               "BitTorrent-1.1",
+                               "BSL-1.0",
+                               "BSD-2-Clause",
+                               "BSD-2-Clause-FreeBSD",
+                               "BSD-2-Clause-NetBSD",
+                               "BSD-3-Clause",
+                               "BSD-3-Clause-Clear",
+                               "BSD-4-Clause",
+                               "BSD-4-Clause-UC",
+                               "CECILL-1.0",
+                               "CECILL-1.1",
+                               "CECILL-2.0",
+                               "CECILL-B",
+                               "CECILL-C",
+                               "ClArtistic",
+                               "CNRI-Python",
+                               "CNRI-Python-GPL-Compatible",
+                               "CPOL-1.02",
+                               "CDDL-1.0",
+                               "CDDL-1.1",
+                               "CPAL-1.0",
+                               "CPL-1.0",
+                               "CATOSL-1.1",
+                               "Condor-1.1",
+                               "CC-BY-1.0",
+                               "CC-BY-2.0",
+                               "CC-BY-2.5",
+                               "CC-BY-3.0",
+                               "CC-BY-ND-1.0",
+                               "CC-BY-ND-2.0",
+                               "CC-BY-ND-2.5",
+                               "CC-BY-ND-3.0",
+                               "CC-BY-NC-1.0",
+                               "CC-BY-NC-2.0",
+                               "CC-BY-NC-2.5",
+                               "CC-BY-NC-3.0",
+                               "CC-BY-NC-ND-1.0",
+                               "CC-BY-NC-ND-2.0",
+                               "CC-BY-NC-ND-2.5",
+                               "CC-BY-NC-ND-3.0",
+                               "CC-BY-NC-SA-1.0",
+                               "CC-BY-NC-SA-2.0",
+                               "CC-BY-NC-SA-2.5",
+                               "CC-BY-NC-SA-3.0",
+                               "CC-BY-SA-1.0",
+                               "CC-BY-SA-2.0",
+                               "CC-BY-SA-2.5",
+                               "CC-BY-SA-3.0",
+                               "CC0-1.0",
+                               "CUA-OPL-1.0",
+                               "D-FSL-1.0",
+                               "WTFPL",
+                               "EPL-1.0",
+                               "eCos-2.0",
+                               "ECL-1.0",
+                               "ECL-2.0",
+                               "EFL-1.0",
+                               "EFL-2.0",
+                               "Entessa",
+                               "ErlPL-1.1",
+                               "EUDatagrid",
+                               "EUPL-1.0",
+                               "EUPL-1.1",
+                               "Fair",
+                               "Frameworx-1.0",
+                               "FTL",
+                               "AGPL-1.0",
+                               "AGPL-3.0",
+                               "GFDL-1.1",
+                               "GFDL-1.2",
+                               "GFDL-1.3",
+                               "GPL-1.0",
+                               "GPL-1.0+",
+                               "GPL-2.0",
+                               "GPL-2.0+",
+                               "GPL-2.0-with-autoconf-exception",
+                               "GPL-2.0-with-bison-exception",
+                               "GPL-2.0-with-classpath-exception",
+                               "GPL-2.0-with-font-exception",
+                               "GPL-2.0-with-GCC-exception",
+                               "GPL-3.0",
+                               "GPL-3.0+",
+                               "GPL-3.0-with-autoconf-exception",
+                               "GPL-3.0-with-GCC-exception",
+                               "LGPL-2.1",
+                               "LGPL-2.1+",
+                               "LGPL-3.0",
+                               "LGPL-3.0+",
+                               "LGPL-2.0",
+                               "LGPL-2.0+",
+                               "gSOAP-1.3b",
+                               "HPND",
+                               "IBM-pibs",
+                               "IPL-1.0",
+                               "Imlib2",
+                               "IJG",
+                               "Intel",
+                               "IPA",
+                               "ISC",
+                               "JSON",
+                               "LPPL-1.3a",
+                               "LPPL-1.0",
+                               "LPPL-1.1",
+                               "LPPL-1.2",
+                               "LPPL-1.3c",
+                               "Libpng",
+                               "LPL-1.02",
+                               "LPL-1.0",
+                               "MS-PL",
+                               "MS-RL",
+                               "MirOS",
+                               "MIT",
+                               "Motosoto",
+                               "MPL-1.0",
+                               "MPL-1.1",
+                               "MPL-2.0",
+                               "MPL-2.0-no-copyleft-exception",
+                               "Multics",
+                               "NASA-1.3",
+                               "Naumen",
+                               "NBPL-1.0",
+                               "NGPL",
+                               "NOSL",
+                               "NPL-1.0",
+                               "NPL-1.1",
+                               "Nokia",
+                               "NPOSL-3.0",
+                               "NTP",
+                               "OCLC-2.0",
+                               "ODbL-1.0",
+                               "PDDL-1.0",
+                               "OGTSL",
+                               "OLDAP-2.2.2",
+                               "OLDAP-1.1",
+                               "OLDAP-1.2",
+                               "OLDAP-1.3",
+                               "OLDAP-1.4",
+                               "OLDAP-2.0",
+                               "OLDAP-2.0.1",
+                               "OLDAP-2.1",
+                               "OLDAP-2.2",
+                               "OLDAP-2.2.1",
+                               "OLDAP-2.3",
+                               "OLDAP-2.4",
+                               "OLDAP-2.5",
+                               "OLDAP-2.6",
+                               "OLDAP-2.7",
+                               "OPL-1.0",
+                               "OSL-1.0",
+                               "OSL-2.0",
+                               "OSL-2.1",
+                               "OSL-3.0",
+                               "OLDAP-2.8",
+                               "OpenSSL",
+                               "PHP-3.0",
+                               "PHP-3.01",
+                               "PostgreSQL",
+                               "Python-2.0",
+                               "QPL-1.0",
+                               "RPSL-1.0",
+                               "RPL-1.1",
+                               "RPL-1.5",
+                               "RHeCos-1.1",
+                               "RSCPL",
+                               "Ruby",
+                               "SAX-PD",
+                               "SGI-B-1.0",
+                               "SGI-B-1.1",
+                               "SGI-B-2.0",
+                               "OFL-1.0",
+                               "OFL-1.1",
+                               "SimPL-2.0",
+                               "Sleepycat",
+                               "SMLNJ",
+                               "SugarCRM-1.1.3",
+                               "SISSL",
+                               "SISSL-1.2",
+                               "SPL-1.0",
+                               "Watcom-1.0",
+                               "NCSA",
+                               "VSL-1.0",
+                               "W3C",
+                               "WXwindows",
+                               "Xnet",
+                               "X11",
+                               "XFree86-1.1",
+                               "YPL-1.0",
+                               "YPL-1.1",
+                               "Zimbra-1.3",
+                               "Zlib",
+                               "ZPL-1.1",
+                               "ZPL-2.0",
+                               "ZPL-2.1",
+                               "Unlicense"
+                       ]
+               },
+               "requires": {
+                       "type": "object",
+                       "description": "Indicates what versions of MediaWiki core are required. This syntax may be extended in the future, for example to check dependencies between other extensions.",
+                       "properties": {
+                               "MediaWiki": {
+                                       "type": "string",
+                                       "description": "Version constraint string against MediaWiki core."
+                               }
+                       }
+               },
+               "ResourceFileModulePaths": {
+                       "type": "object",
+                       "description": "Default paths to use for all ResourceLoader file modules",
+                       "additionalProperties": false,
+                       "properties": {
+                               "localBasePath": {
+                                       "type": "string",
+                                       "description": "Base path to prepend to all local paths, relative to current directory"
+                               },
+                               "remoteExtPath": {
+                                       "type": "string",
+                                       "description": "Base path to prepend to all remote paths, relative to $wgExtensionAssetsPath"
+                               },
+                               "remoteSkinPath": {
+                                       "type": "string",
+                                       "description": "Base path to prepend to all remote paths, relative to $wgStylePath"
+                               }
+                       }
+               },
+               "ResourceModules": {
+                       "type": "object",
+                       "description": "ResourceLoader modules to register",
+                       "patternProperties": {
+                               "^[a-zA-Z0-9-\\.]+$": {
+                                       "type": "object",
+                                       "anyOf": [
+                                               {
+                                                       "description": "A ResourceLoaderFileModule definition",
+                                                       "additionalProperties": false,
+                                                       "properties": {
+                                                               "localBasePath": {
+                                                                       "type": "string",
+                                                                       "description": "Base path to prepend to all local paths in $options. Defaults to $IP"
+                                                               },
+                                                               "remoteBasePath": {
+                                                                       "type": "string",
+                                                                       "description": "Base path to prepend to all remote paths in $options. Defaults to $wgScriptPath"
+                                                               },
+                                                               "remoteExtPath": {
+                                                                       "type": "string",
+                                                                       "description": "Equivalent of remoteBasePath, but relative to $wgExtensionAssetsPath"
+                                                               },
+                                                               "skipFunction": {
+                                                                       "type": "string",
+                                                                       "description": "Path to a file containing a JavaScript \"skip function\", if desired."
+                                                               },
+                                                               "scripts": {
+                                                                       "type": ["string", "array"],
+                                                                       "description": "Scripts to always include (array of file paths)",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               },
+                                                               "languageScripts": {
+                                                                       "type": "object",
+                                                                       "description": "Scripts to include in specific language contexts (mapping of language code to file path(s))",
+                                                                       "patternProperties": {
+                                                                               "^[a-zA-Z0-9-]{2,}$": {
+                                                                                       "type": [
+                                                                                               "string",
+                                                                                               "array"
+                                                                                       ],
+                                                                                       "items": {
+                                                                                               "type": "string"
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               },
+                                                               "skinScripts": {
+                                                                       "type": "object",
+                                                                       "description": "Scripts to include in specific skin contexts (mapping of skin name to script(s)",
+                                                                       "patternProperties": {
+                                                                               ".+": {
+                                                                                       "type": [
+                                                                                               "string",
+                                                                                               "array"
+                                                                                       ],
+                                                                                       "items": {
+                                                                                               "type": "string"
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               },
+                                                               "debugScripts": {
+                                                                       "type": ["string", "array"],
+                                                                       "description": "Scripts to include in debug contexts",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               },
+                                                               "loaderScripts": {
+                                                                       "type": ["string", "array"],
+                                                                       "description": "Scripts to include in the startup module",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               },
+                                                               "dependencies": {
+                                                                       "type": ["string", "array"],
+                                                                       "description": "Modules which must be loaded before this module",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               },
+                                                               "styles": {
+                                                                       "type": ["string", "array", "object"],
+                                                                       "description": "Styles to always load",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               },
+                                                               "skinStyles": {
+                                                                       "type": "object",
+                                                                       "description": "Styles to include in specific skin contexts (mapping of skin name to style(s))",
+                                                                       "patternProperties": {
+                                                                               ".+": {
+                                                                                       "type": [
+                                                                                               "string",
+                                                                                               "array"
+                                                                                       ],
+                                                                                       "items": {
+                                                                                               "type": "string"
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               },
+                                                               "messages": {
+                                                                       "type": ["string", "array"],
+                                                                       "description": "Messages to always load",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               },
+                                                               "group": {
+                                                                       "type": "string",
+                                                                       "description": "Group which this module should be loaded together with"
+                                                               },
+                                                               "position": {
+                                                                       "type": "string",
+                                                                       "description": "Position on the page to load this module at",
+                                                                       "enum": [
+                                                                               "bottom",
+                                                                               "top"
+                                                                       ]
+                                                               },
+                                                               "templates": {
+                                                                       "type": ["object", "array"],
+                                                                       "description": "Templates to be loaded for client-side usage"
+                                                               },
+                                                               "targets": {
+                                                                       "type": ["string", "array"],
+                                                                       "description": "ResourceLoader target the module can run on",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               }
+                                                       }
+                                               },
+                                               {
+                                                       "description": "A ResourceLoaderWikiModule definition",
+                                                       "additionalProperties": false,
+                                                       "properties": {
+                                                               "class": {
+                                                                       "enum": ["ResourceLoaderWikiModule"]
+                                                               },
+                                                               "group": {
+                                                                       "type": "string",
+                                                                       "description": "Group which this module should be loaded together with"
+                                                               },
+                                                               "position": {
+                                                                       "type": "string",
+                                                                       "description": "Position on the page to load this module at",
+                                                                       "enum": [
+                                                                               "bottom",
+                                                                               "top"
+                                                                       ]
+                                                               },
+                                                               "targets": {
+                                                                       "type": ["string", "array"],
+                                                                       "description": "ResourceLoader target the module can run on",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               },
+                                                               "scripts": {
+                                                                       "type": "array",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               },
+                                                               "styles": {
+                                                                       "type": "array",
+                                                                       "items": {
+                                                                               "type": "string"
+                                                                       }
+                                                               }
+                                                       }
+                                               },
+                                               {
+                                                       "description": "A ResourceLoaderImageModule definition",
+                                                       "additionalProperties": false,
+                                                       "properties": {
+                                                               "class": {
+                                                                       "enum": ["ResourceLoaderImageModule"]
+                                                               },
+                                                               "data": {
+                                                                       "type": "string"
+                                                               },
+                                                               "prefix": {
+                                                                       "type": "string"
+                                                               },
+                                                               "selector": {
+                                                                       "type": "string"
+                                                               },
+                                                               "selectorWithoutVariant": {
+                                                                       "type": "string"
+                                                               },
+                                                               "selectorWithVariant": {
+                                                                       "type": "string"
+                                                               },
+                                                               "variants": {
+                                                                       "type": "object"
+                                                               },
+                                                               "images": {
+                                                                       "type": "object"
+                                                               },
+                                                               "position": {
+                                                                       "enum": [
+                                                                               "top",
+                                                                               "bottom"
+                                                                       ]
+                                                               }
+                                                       }
+                                               },
+                                               {
+                                                       "description": "An arbitrary ResourceLoaderModule definition",
+                                                       "properties": {
+                                                               "class": {
+                                                                       "type": "string",
+                                                                       "pattern": "^((?!ResourceLoader(File|Image)Module).)*$"
+                                                               }
+                                                       },
+                                                       "required": ["class"]
+                                               }
+                                       ]
+                               }
+                       }
+               },
+               "ResourceModuleSkinStyles": {
+                       "type": "object",
+                       "description": "ResourceLoader modules for custom skin styles"
+               },
+               "ResourceLoaderSources": {
+                       "type": "object",
+                       "description": "ResourceLoader sources to register"
+               },
+               "ResourceLoaderLESSVars": {
+                       "type": "object",
+                       "description": "ResourceLoader LESS variables"
+               },
+               "ConfigRegistry": {
+                       "type": "object",
+                       "description": "Registry of factory functions to create Config objects"
+               },
+               "SessionProviders": {
+                       "type": "object",
+                       "description": "Session providers"
+               },
+               "AuthManagerAutoConfig": {
+                       "type": "object",
+                       "description": "AuthManager auto-configuration",
+                       "additionalProperties": false,
+                       "properties": {
+                               "preauth": {
+                                       "type": "object",
+                                       "description": "Pre-authentication providers"
+                               },
+                               "primaryauth": {
+                                       "type": "object",
+                                       "description": "Primary authentication providers"
+                               },
+                               "secondaryauth": {
+                                       "type": "object",
+                                       "description": "Secondary authentication providers"
+                               }
+                       }
+               },
+               "CentralIdLookupProviders": {
+                       "type": "object",
+                       "description": "Central ID lookup providers"
+               },
+               "namespaces": {
+                       "type": "array",
+                       "description": "Method to add extra namespaces",
+                       "items": {
+                               "type": "object",
+                               "properties": {
+                                       "id": {
+                                               "type": "integer"
+                                       },
+                                       "constant": {
+                                               "type": "string"
+                                       },
+                                       "name": {
+                                               "type": "string"
+                                       },
+                                       "gender": {
+                                               "type": "object",
+                                               "properties": {
+                                                       "male": {
+                                                               "type": "string"
+                                                       },
+                                                       "female": {
+                                                               "type": "string"
+                                                       }
+                                               }
+                                       },
+                                       "subpages": {
+                                               "type": "boolean",
+                                               "default": false
+                                       },
+                                       "content": {
+                                               "type": "boolean",
+                                               "default": false
+                                       },
+                                       "defaultcontentmodel": {
+                                               "type": "string"
+                                       },
+                                       "protection": {
+                                               "type": ["string", "array"],
+                                               "description": "Userright(s) required to edit in this namespace"
+                                       },
+                                       "capitallinkoverride": {
+                                               "type": "boolean",
+                                               "description": "Set $wgCapitalLinks on a per-namespace basis"
+                                       }
+                               },
+                               "required": ["id", "constant", "name"]
+                       }
+               },
+               "TrackingCategories": {
+                       "type": "array",
+                       "description": "Tracking category message keys",
+                       "items": {
+                               "type": "string"
+                       }
+               },
+               "DefaultUserOptions": {
+                       "type": "object",
+                       "description": "Default values of user options"
+               },
+               "HiddenPrefs": {
+                       "type": "array",
+                       "description": "Preferences users cannot set",
+                       "items": {
+                               "type": "string"
+                       }
+               },
+               "GroupPermissions": {
+                       "type": "object",
+                       "description": "Default permissions to give to user groups",
+                       "patternProperties": {
+                               "^[a-z]+$": {
+                                       "type": "object",
+                                       "patternProperties": {
+                                               "^[a-z]+$": {
+                                                       "type": "boolean"
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "RevokePermissions": {
+                       "type": "object",
+                       "description": "Default permissions to revoke from user groups",
+                       "patternProperties": {
+                               "^[a-z]+$": {
+                                       "type": "object",
+                                       "patternProperties": {
+                                               "^[a-z]+$": {
+                                                       "type": "boolean"
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "GrantPermissions": {
+                       "type": "object",
+                       "description": "Map of permissions granted to authorized consumers to their bundles, called 'grants'",
+                       "patternProperties": {
+                               "^[a-z]+$": {
+                                       "type": "object",
+                                       "patternProperties": {
+                                               "^[a-z]+$": {
+                                                       "type": "boolean"
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "GrantPermissionGroups": {
+                       "type": "object",
+                       "description": "Map of grants to their UI grouping",
+                       "patternProperties": {
+                               "^[a-z]+$": {
+                                       "type": "string"
+                               }
+                       }
+               },
+               "ImplicitGroups": {
+                       "type": "array",
+                       "description": "Implicit groups"
+               },
+               "GroupsAddToSelf": {
+                       "type": "object",
+                       "description": "Groups a user can add to themselves"
+               },
+               "GroupsRemoveFromSelf": {
+                       "type": "object",
+                       "description": "Groups a user can remove from themselves"
+               },
+               "AddGroups": {
+                       "type": "object",
+                       "description": "Groups a user can add to users"
+               },
+               "RemoveGroups": {
+                       "type": "object",
+                       "description": "Groups a user can remove from users"
+               },
+               "AvailableRights": {
+                       "type": "array",
+                       "description": "User rights added by the extension",
+                       "items": {
+                               "type": "string"
+                       }
+               },
+               "ContentHandlers": {
+                       "type": "object",
+                       "description": "Mapping of model ID to class name",
+                       "patternProperties": {
+                               "^[A-Za-z]+$": {
+                                       "type": "string"
+                               }
+                       }
+               },
+               "RateLimits": {
+                       "type": "object",
+                       "description": "Rate limits"
+               },
+               "RecentChangesFlags": {
+                       "type": "object",
+                       "description": "Flags (letter symbols) shown on RecentChanges pages"
+               },
+               "MediaHandlers": {
+                       "type": "object",
+                       "description": "Plugins for media file type handling. Each entry in the array maps a MIME type to a PHP class name."
+               },
+               "ExtensionFunctions": {
+                       "type": [
+                               "array",
+                               "string"
+                       ],
+                       "description": "Function to call after setup has finished",
+                       "items": {
+                               "type": "string"
+                       }
+               },
+               "ExtensionMessagesFiles": {
+                       "type": "object",
+                       "description": "File paths containing PHP internationalization data"
+               },
+               "MessagesDirs": {
+                       "type": "object",
+                       "description": "Directory paths containing JSON internationalization data"
+               },
+               "ExtensionEntryPointListFiles": {
+                       "type": "object"
+               },
+               "SpecialPages": {
+                       "type": "object",
+                       "description": "SpecialPages implemented in this extension (mapping of page name to class name)"
+               },
+               "AutoloadClasses": {
+                       "type": "object"
+               },
+               "Hooks": {
+                       "type": [ "string", "object" ],
+                       "description": "Hooks this extension uses (mapping of hook name to callback)"
+               },
+               "JobClasses": {
+                       "type": "object",
+                       "description": "Job types this extension implements (mapping of job type to class name)"
+               },
+               "LogTypes": {
+                       "type": "array",
+                       "description": "List of new log types this extension uses"
+               },
+               "LogRestrictions": {
+                       "type": "object"
+               },
+               "FilterLogTypes": {
+                       "type": "object"
+               },
+               "ActionFilteredLogs": {
+                       "type": "object",
+                       "description": "List of log types which can be filtered by log actions",
+                       "patternProperties": {
+                               "^[a-z-]+$": {
+                                       "type": "object",
+                                       "patternProperties": {
+                                               "^[a-z-]+$": {
+                                                       "type": "array",
+                                                       "items": {
+                                                               "type": "string"
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "LogNames": {
+                       "type": "object"
+               },
+               "LogHeaders": {
+                       "type": "object"
+               },
+               "LogActions": {
+                       "type": "object"
+               },
+               "LogActionsHandlers": {
+                       "type": "object"
+               },
+               "Actions": {
+                       "type": "object"
+               },
+               "APIModules": {
+                       "type": "object"
+               },
+               "APIFormatModules": {
+                       "type": "object"
+               },
+               "APIMetaModules": {
+                       "type": "object"
+               },
+               "APIPropModules": {
+                       "type": "object"
+               },
+               "APIListModules": {
+                       "type": "object"
+               },
+               "ValidSkinNames": {
+                       "type": "object"
+               },
+               "FeedClasses": {
+                       "type": "object",
+                       "description": "Available feeds objects"
+               },
+               "SkinOOUIThemes": {
+                       "type": "object"
+               },
+               "callback": {
+                       "type": [
+                               "array",
+                               "string"
+                       ],
+                       "description": "A function to be called right after MediaWiki processes this file"
+               },
+               "config": {
+                       "type": "object",
+                       "description": "Configuration options for this extension",
+                       "properties": {
+                               "_prefix": {
+                                       "type": "string",
+                                       "default": "wg",
+                                       "description": "Prefix to put in front of configuration settings when exporting them to $GLOBALS"
+                               }
+                       },
+                       "patternProperties": {
+                               "^[a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*$": {
+                                       "properties": {
+                                               "_merge_strategy": {
+                                                       "type": "string",
+                                                       "enum": [
+                                                               "array_merge_recursive",
+                                                               "array_plus_2d",
+                                                               "array_plus",
+                                                               "array_merge"
+                                                       ],
+                                                       "default": "array_merge"
+                                               }
+                                       }
+                               }
+                       }
+               },
+               "ParserTestFiles": {
+                       "type": "array",
+                       "description": "Parser test suite files to be run by parserTests.php when no specific filename is passed to it"
+               },
+               "load_composer_autoloader": {
+                       "type": "boolean",
+                       "description": "Load the composer autoloader for this extension, if one is present"
+               }
+       }
+}
index d65fb78..e1b3974 100644 (file)
@@ -903,6 +903,7 @@ $image: File
 'BlockIpComplete': After an IP address or user is blocked.
 $block: the Block object that was saved
 $user: the user who did the block (not the one being blocked)
+$priorBlock: the Block object for the prior block or null if there was none
 
 'BookInformation': Before information output on Special:Booksources.
 $isbn: ISBN to show information for
@@ -3302,9 +3303,10 @@ in most cases over UploadVerification.
 $upload: (object) an instance of UploadBase, with all info about the upload
 $mime: (string) The uploaded file's MIME type, as detected by MediaWiki.
   Handlers will typically only apply for specific MIME types.
-&$error: (object) output: true if the file is valid. Otherwise, an indexed array
-  representing the problem with the file, where the first element is the message
-  key and the remaining elements are used as parameters to the message.
+&$error: (object) output: true if the file is valid. Otherwise, set this to the reason
+  in the form of array( messagename, param1, param2, ... ) or a MessageSpecifier
+  instance (you might want to use ApiMessage to provide machine-readable details
+  for the API).
 
 'UploadVerifyUpload': Upload verification, based on both file properties like
 MIME type (same as UploadVerifyFile) and the information entered by the user
@@ -3465,6 +3467,9 @@ $user: User object for the logged-in user
 For functionality that needs to run after any login (API or web) use UserLoggedIn.
 &$user: the user object that was created on login
 &$inject_html: Any HTML to inject after the "logged in" message.
+$direct: (bool) The hook is called directly after a successful login. This will only happen once
+  per login. A UserLoginComplete call with direct=false can happen when the user visits the login
+  page while already logged in.
 
 'UserLoginForm': DEPRECATED! Create an AuthenticationProvider instead.
 Manipulate the login form.
index d636188..fa1609f 100644 (file)
@@ -162,13 +162,21 @@ function wfImageAuthMain() {
                }
        }
 
+       $options = []; // HTTP header options
+       if ( isset( $_SERVER['HTTP_RANGE'] ) ) {
+               $options['range'] = $_SERVER['HTTP_RANGE'];
+       }
+       if ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
+               $options['if-modified-since'] = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
+       }
+
        if ( $request->getCheck( 'download' ) ) {
                $headers[] = 'Content-Disposition: attachment';
        }
 
        // Stream the requested file
        wfDebugLog( 'img_auth', "Streaming `" . $filename . "`." );
-       $repo->streamFile( $filename, $headers );
+       $repo->streamFile( $filename, $headers, $options );
 }
 
 /**
index 28b566a..531e0be 100644 (file)
@@ -79,6 +79,11 @@ class Category {
                                $this->mSubcats = 0;
                                $this->mFiles = 0;
 
+                               # If the title exists, call refreshCounts to add a row for it.
+                               if ( $this->mTitle->exists() ) {
+                                       DeferredUpdates::addCallableUpdate( [ $this, 'refreshCounts' ] );
+                               }
+
                                return true;
                        } else {
                                return false; # Fail
@@ -331,21 +336,35 @@ class Category {
                        [ 'LOCK IN SHARE MODE' ]
                );
 
+               $shouldExist = $result->pages > 0 || $this->getTitle()->exists();
+
                if ( $this->mID ) {
-                       # The category row already exists, so do a plain UPDATE instead
-                       # of INSERT...ON DUPLICATE KEY UPDATE to avoid creating a gap
-                       # in the cat_id sequence. The row may or may not be "affected".
-                       $dbw->update(
-                               'category',
-                               [
-                                       'cat_pages' => $result->pages,
-                                       'cat_subcats' => $result->subcats,
-                                       'cat_files' => $result->files
-                               ],
-                               [ 'cat_title' => $this->mName ],
-                               __METHOD__
-                       );
-               } else {
+                       if ( $shouldExist ) {
+                               # The category row already exists, so do a plain UPDATE instead
+                               # of INSERT...ON DUPLICATE KEY UPDATE to avoid creating a gap
+                               # in the cat_id sequence. The row may or may not be "affected".
+                               $dbw->update(
+                                       'category',
+                                       [
+                                               'cat_pages' => $result->pages,
+                                               'cat_subcats' => $result->subcats,
+                                               'cat_files' => $result->files
+                                       ],
+                                       [ 'cat_title' => $this->mName ],
+                                       __METHOD__
+                               );
+                       } else {
+                               # The category is empty and has no description page, delete it
+                               $dbw->delete(
+                                       'category',
+                                       [ 'cat_title' => $this->mName ],
+                                       __METHOD__
+                               );
+                               $this->mID = false;
+                       }
+               } elseif ( $shouldExist ) {
+                       # The category row doesn't exist but should, so create it. Use
+                       # upsert in case of races.
                        $dbw->upsert(
                                'category',
                                [
@@ -362,6 +381,8 @@ class Category {
                                ],
                                __METHOD__
                        );
+                       // @todo: Should we update $this->mID here? Or not since Category
+                       // objects tend to be short lived enough to not matter?
                }
 
                $dbw->endAtomic( __METHOD__ );
index 389b077..8dd3f5c 100644 (file)
@@ -532,17 +532,17 @@ class CategoryViewer extends ContextSource {
        }
 
        /**
-        * Format a list of articles chunked by letter in a three-column
-        * list, ordered vertically.
+        * Format a list of articles chunked by letter in a three-column list, ordered
+        * vertically. This is used for categories with a significant number of pages.
         *
         * TODO: Take the headers into account when creating columns, so they're
         * more visually equal.
         *
         * TODO: shortList and columnList are similar, need merging
         *
-        * @param array $articles
-        * @param string[] $articles_start_char
-        * @return string
+        * @param string[] $articles HTML links to each article
+        * @param string[] $articles_start_char The header characters for each article
+        * @return string HTML to output
         * @private
         */
        static function columnList( $articles, $articles_start_char ) {
@@ -579,10 +579,11 @@ class CategoryViewer extends ContextSource {
        }
 
        /**
-        * Format a list of articles chunked by letter in a bullet list.
-        * @param array $articles
-        * @param string[] $articles_start_char
-        * @return string
+        * Format a list of articles chunked by letter in a bullet list. This is used
+        * for categories with a small number of pages (when columns aren't needed).
+        * @param string[] $articles HTML links to each article
+        * @param string[] $articles_start_char The header characters for each article
+        * @return string HTML to output
         * @private
         */
        static function shortList( $articles, $articles_start_char ) {
index 722dfe3..1e60302 100644 (file)
@@ -1444,7 +1444,10 @@ $wgGalleryOptions = [
        'imagesPerRow' => 0, // Default number of images per-row in the gallery. 0 -> Adapt to screensize
        'imageWidth' => 120, // Width of the cells containing images in galleries (in "px")
        'imageHeight' => 120, // Height of the cells containing images in galleries (in "px")
-       'captionLength' => 25, // Length to truncate filename to in caption when using "showfilename"
+       'captionLength' => true, // Deprecated @since 1.28
+                                // Length to truncate filename to in caption when using "showfilename".
+                                // A value of 'true' will truncate the filename to one line using CSS
+                                // and will be the behaviour after deprecation.
        'showBytes' => true, // Show the filesize in bytes in categories
        'mode' => 'traditional',
 ];
@@ -2882,15 +2885,6 @@ $wgDummyLanguageCodes = [
        'zh-yue' => 'yue',
 ];
 
-/**
- * Character set for use in the article edit box. Language-specific encodings
- * may be defined.
- *
- * This historic feature is one of the first that was added by former MediaWiki
- * team leader Brion Vibber, and is used to support the Esperanto x-system.
- */
-$wgEditEncoding = '';
-
 /**
  * Set this to true to replace Arabic presentation forms with their standard
  * forms in the U+0600-U+06FF block. This only works if $wgLanguageCode is
@@ -4216,6 +4210,8 @@ $wgAllowImageTag = false;
  *    - RaggettInternalHHVM: Use the limited-functionality HHVM extension
  *    - RaggettInternalPHP: Use the PECL extension
  *    - RaggettExternal: Shell out to an external binary (tidyBin)
+ *    - Html5Depurate: Use external Depurate service
+ *    - Html5Internal: Use the built-in HTML5 balancer
  *
  *  - tidyConfigFile: Path to configuration file for any of the Raggett drivers
  *  - debugComment: True to add a comment to the output with warning messages
@@ -8344,6 +8340,21 @@ $wgEventRelayerConfig = [
        ]
 ];
 
+/**
+ * Share data about this installation with MediaWiki developers
+ *
+ * When set to true, MediaWiki will periodically ping https://www.mediawiki.org/ with basic
+ * data about this MediaWiki instance. This data includes, for example, the type of system,
+ * PHP version, and chosen database backend. The Wikimedia Foundation shares this data with
+ * MediaWiki developers to help guide future development efforts.
+ *
+ * For details about what data is sent, see: https://www.mediawiki.org/wiki/Pingback
+ *
+ * @var bool
+ * @since 1.28
+ */
+$wgPingback = false;
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker
index d9330ee..ba24799 100644 (file)
@@ -47,7 +47,11 @@ class DummyLinker {
                );
        }
 
+       /**
+        * @deprecated since 1.28, use LinkRenderer::getLinkClasses() instead
+        */
        public function getLinkColour( $t, $threshold ) {
+               wfDeprecated( __METHOD__, '1.28' );
                return Linker::getLinkColour( $t, $threshold );
        }
 
index 9c7ccdf..e4146c5 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\Logger\LoggerFactory;
+
 /**
  * The edit page/HTML interface (split from Article)
  * The actual database and text munging is still in Article,
@@ -1249,9 +1251,31 @@ class EditPage {
 
                        return $handler->makeEmptyContent();
                } else {
-                       # nasty side-effect, but needed for consistency
-                       $this->contentModel = $rev->getContentModel();
-                       $this->contentFormat = $rev->getContentFormat();
+                       // Content models should always be the same since we error
+                       // out if they are different before this point.
+                       $logger = LoggerFactory::getInstance( 'editpage' );
+                       if ( $this->contentModel !== $rev->getContentModel() ) {
+                               $logger->warning( "Overriding content model from current edit {prev} to {new}", [
+                                       'prev' => $this->contentModel,
+                                       'new' => $rev->getContentModel(),
+                                       'title' => $this->getTitle()->getPrefixedDBkey(),
+                                       'method' => __METHOD__
+                               ] );
+                               $this->contentModel = $rev->getContentModel();
+                       }
+
+                       // Given that the content models should match, the current selected
+                       // format should be supported.
+                       if ( !$content->isSupportedFormat( $this->contentFormat ) ) {
+                               $logger->warning( "Current revision content format unsupported. Overriding {prev} to {new}", [
+
+                                       'prev' => $this->contentFormat,
+                                       'new' => $rev->getContentFormat(),
+                                       'title' => $this->getTitle()->getPrefixedDBkey(),
+                                       'method' => __METHOD__
+                               ] );
+                               $this->contentFormat = $rev->getContentFormat();
+                       }
 
                        return $content;
                }
@@ -3026,7 +3050,7 @@ class EditPage {
         * @param string $summary The text of the summary to display
         */
        protected function showSummaryInput( $isSubjectPreview, $summary = "" ) {
-               global $wgOut, $wgContLang;
+               global $wgOut;
                # Add a class if 'missingsummary' is triggered to allow styling of the summary line
                $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
                if ( $isSubjectPreview ) {
@@ -3038,7 +3062,6 @@ class EditPage {
                                return;
                        }
                }
-               $summary = $wgContLang->recodeForEdit( $summary );
                $labelText = wfMessage( $isSubjectPreview ? 'subject' : 'summary' )->parse();
                list( $label, $input ) = $this->getSummaryInput(
                        $summary,
@@ -4175,11 +4198,9 @@ HTML
         * @return string
         */
        protected function safeUnicodeOutput( $text ) {
-               global $wgContLang;
-               $codedText = $wgContLang->recodeForEdit( $text );
                return $this->checkUnicodeCompliantBrowser()
-                       ? $codedText
-                       : $this->makeSafe( $codedText );
+                       ? $text
+                       : $this->makesafe( $text );
        }
 
        /**
index 98f8283..361058b 100644 (file)
@@ -203,7 +203,7 @@ class FileDeleteForm {
                                                $dbw->endAtomic( __METHOD__ );
                                        } else {
                                                // Page deleted but file still there? rollback page delete
-                                               $dbw->rollback( __METHOD__ );
+                                               wfGetLBFactory()->rollbackMasterChanges( __METHOD__ );
                                        }
                                } else {
                                        // Done; nothing changed
index e5128d1..7cb75bb 100644 (file)
@@ -935,13 +935,7 @@ class Html {
                        $attribs['version'] = $wgHtml5Version;
                }
 
-               $html = self::openElement( 'html', $attribs );
-
-               if ( $html ) {
-                       $html .= "\n";
-               }
-
-               $ret .= $html;
+               $ret .= self::openElement( 'html', $attribs );
 
                return $ret;
        }
@@ -1020,9 +1014,21 @@ class Html {
        static function srcSet( array $urls ) {
                $candidates = [];
                foreach ( $urls as $density => $url ) {
-                       // Cast density to float to strip 'x'.
-                       $candidates[] = $url . ' ' . (float)$density . 'x';
+                       // Cast density to float to strip 'x', then back to string to serve
+                       // as array index.
+                       $density = (string)(float)$density;
+                       $candidates[$density] = $url;
                }
+
+               // Remove duplicates that are the same as a smaller value
+               ksort( $candidates, SORT_NUMERIC );
+               $candidates = array_unique( $candidates );
+
+               // Append density info to the url
+               foreach ( $candidates as $density => $url ) {
+                       $candidates[$density] = $url . ' ' . $density . 'x';
+               }
+
                return implode( ", ", $candidates );
        }
 }
index b12f49f..54b057a 100644 (file)
@@ -124,47 +124,6 @@ class Http {
                return Http::request( 'POST', $url, $options, $caller );
        }
 
-       /**
-        * Check if the URL can be served by localhost
-        *
-        * @param string $url Full url to check
-        * @return bool
-        */
-       public static function isLocalURL( $url ) {
-               global $wgCommandLineMode, $wgLocalVirtualHosts;
-
-               if ( $wgCommandLineMode ) {
-                       return false;
-               }
-
-               // Extract host part
-               $matches = [];
-               if ( preg_match( '!^http://([\w.-]+)[/:].*$!', $url, $matches ) ) {
-                       $host = $matches[1];
-                       // Split up dotwise
-                       $domainParts = explode( '.', $host );
-                       // Check if this domain or any superdomain is listed as a local virtual host
-                       $domainParts = array_reverse( $domainParts );
-
-                       $domain = '';
-                       $countParts = count( $domainParts );
-                       for ( $i = 0; $i < $countParts; $i++ ) {
-                               $domainPart = $domainParts[$i];
-                               if ( $i == 0 ) {
-                                       $domain = $domainPart;
-                               } else {
-                                       $domain = $domainPart . '.' . $domain;
-                               }
-
-                               if ( in_array( $domain, $wgLocalVirtualHosts ) ) {
-                                       return true;
-                               }
-                       }
-               }
-
-               return false;
-       }
-
        /**
         * A standard user-agent we can use for external requests.
         * @return string
@@ -194,7 +153,7 @@ class Http {
        }
 
        /**
-        * Gets the relevant proxy from $wgHTTPProxy/http_proxy (when set).
+        * Gets the relevant proxy from $wgHTTPProxy
         *
         * @return mixed The proxy address or an empty string if not set.
         */
@@ -205,11 +164,6 @@ class Http {
                        return $wgHTTPProxy;
                }
 
-               $envHttpProxy = getenv( "http_proxy" );
-               if ( $envHttpProxy ) {
-                       return $envHttpProxy;
-               }
-
                return "";
        }
 }
@@ -393,15 +347,56 @@ class MWHttpRequest {
                        return;
                }
 
-               // Otherwise, fallback to $wgHTTPProxy/http_proxy (when set) if this is not a machine
+               // Otherwise, fallback to $wgHTTPProxy if this is not a machine
                // local URL and proxies are not disabled
-               if ( Http::isLocalURL( $this->url ) || $this->noProxy ) {
+               if ( self::isLocalURL( $this->url ) || $this->noProxy ) {
                        $this->proxy = '';
                } else {
                        $this->proxy = Http::getProxy();
                }
        }
 
+       /**
+        * Check if the URL can be served by localhost
+        *
+        * @param string $url Full url to check
+        * @return bool
+        */
+       private static function isLocalURL( $url ) {
+               global $wgCommandLineMode, $wgLocalVirtualHosts;
+
+               if ( $wgCommandLineMode ) {
+                       return false;
+               }
+
+               // Extract host part
+               $matches = [];
+               if ( preg_match( '!^https?://([\w.-]+)[/:].*$!', $url, $matches ) ) {
+                       $host = $matches[1];
+                       // Split up dotwise
+                       $domainParts = explode( '.', $host );
+                       // Check if this domain or any superdomain is listed as a local virtual host
+                       $domainParts = array_reverse( $domainParts );
+
+                       $domain = '';
+                       $countParts = count( $domainParts );
+                       for ( $i = 0; $i < $countParts; $i++ ) {
+                               $domainPart = $domainParts[$i];
+                               if ( $i == 0 ) {
+                                       $domain = $domainPart;
+                               } else {
+                                       $domain = $domainPart . '.' . $domain;
+                               }
+
+                               if ( in_array( $domain, $wgLocalVirtualHosts ) ) {
+                                       return true;
+                               }
+                       }
+               }
+
+               return false;
+       }
+
        /**
         * Set the user agent
         * @param string $UA
index 0b2d3a7..1979e44 100644 (file)
@@ -137,31 +137,24 @@ class Linker {
        /**
         * Return the CSS colour of a known link
         *
+        * @deprecated since 1.28, use LinkRenderer::getLinkClasses() instead
+        *
         * @since 1.16.3
         * @param LinkTarget $t
         * @param int $threshold User defined threshold
         * @return string CSS class
         */
        public static function getLinkColour( LinkTarget $t, $threshold ) {
-               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
-               // Make sure the target is in the cache
-               $id = $linkCache->addLinkObj( $t );
-               if ( $id == 0 ) {
-                       // Doesn't exist
-                       return '';
-               }
-
-               if ( $linkCache->getGoodLinkFieldObj( $t, 'redirect' ) ) {
-                       # Page is a redirect
-                       return 'mw-redirect';
-               } elseif ( $threshold > 0 && MWNamespace::isContent( $t->getNamespace() )
-                       && $linkCache->getGoodLinkFieldObj( $t, 'length' ) < $threshold
-               ) {
-                       # Page is a stub
-                       return 'stub';
+               wfDeprecated( __METHOD__, '1.28' );
+               $services = MediaWikiServices::getInstance();
+               $linkRenderer = $services->getLinkRenderer();
+               if ( $threshold !== $linkRenderer->getStubThreshold() ) {
+                       // Need to create a new instance with the right stub threshold...
+                       $linkRenderer = $services->getLinkRendererFactory()->create();
+                       $linkRenderer->setStubThreshold( $threshold );
                }
 
-               return '';
+               return $linkRenderer->getLinkClasses( $t );
        }
 
        /**
index 15b70c8..ecc719a 100644 (file)
@@ -23,6 +23,7 @@
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\Session\SessionManager;
 use WrappedString\WrappedString;
+use WrappedString\WrappedStringList;
 
 /**
  * This class should be covered by a general architecture document which does
@@ -250,11 +251,6 @@ class OutputPage extends ContextSource {
         */
        protected $styles = [];
 
-       /**
-        * Whether jQuery is already handled.
-        */
-       protected $mJQueryDone = false;
-
        private $mIndexPolicy = 'index';
        private $mFollowPolicy = 'follow';
        private $mVaryHeader = [
@@ -2633,7 +2629,8 @@ class OutputPage extends ContextSource {
                $userdir = $this->getLanguage()->getDir();
                $sitedir = $wgContLang->getDir();
 
-               $ret = Html::htmlHeader( $sk->getHtmlElementAttributes() );
+               $pieces = [];
+               $pieces[] = Html::htmlHeader( $sk->getHtmlElementAttributes() );
 
                if ( $this->getHTMLTitle() == '' ) {
                        $this->setHTMLTitle( $this->msg( 'pagetitle', $this->getPageTitle() )->inContentLanguage() );
@@ -2641,8 +2638,7 @@ class OutputPage extends ContextSource {
 
                $openHead = Html::openElement( 'head' );
                if ( $openHead ) {
-                       # Don't bother with the newline if $head == ''
-                       $ret .= "$openHead\n";
+                       $pieces[] = $openHead;
                }
 
                if ( !Html::isXmlMimeType( $this->getConfig()->get( 'MimeType' ) ) ) {
@@ -2654,25 +2650,25 @@ class OutputPage extends ContextSource {
                        // Our XML declaration is output by Html::htmlHeader.
                        // http://www.whatwg.org/html/semantics.html#attr-meta-http-equiv-content-type
                        // http://www.whatwg.org/html/semantics.html#charset
-                       $ret .= Html::element( 'meta', [ 'charset' => 'UTF-8' ] ) . "\n";
+                       $pieces[] = Html::element( 'meta', [ 'charset' => 'UTF-8' ] );
                }
 
-               $ret .= Html::element( 'title', null, $this->getHTMLTitle() ) . "\n";
-               $ret .= $this->getInlineHeadScripts() . "\n";
-               $ret .= $this->buildCssLinks() . "\n";
-               $ret .= $this->getExternalHeadScripts() . "\n";
+               $pieces[] = Html::element( 'title', null, $this->getHTMLTitle() );
+               $pieces[] = $this->getInlineHeadScripts();
+               $pieces[] = $this->buildCssLinks();
+               $pieces[] = $this->getExternalHeadScripts();
 
                foreach ( $this->getHeadLinksArray() as $item ) {
-                       $ret .= $item . "\n";
+                       $pieces[] = $item;
                }
 
                foreach ( $this->mHeadItems as $item ) {
-                       $ret .= $item . "\n";
+                       $pieces[] = $item;
                }
 
                $closeHead = Html::closeElement( 'head' );
                if ( $closeHead ) {
-                       $ret .= "$closeHead\n";
+                       $pieces[] = $closeHead;
                }
 
                $bodyClasses = [];
@@ -2687,6 +2683,11 @@ class OutputPage extends ContextSource {
                        $bodyClasses[] = 'capitalize-all-nouns';
                }
 
+               // Parser feature migration class
+               // The idea is that this will eventually be removed, after the wikitext
+               // which requires it is cleaned up.
+               $bodyClasses[] = 'mw-hide-empty-elt';
+
                $bodyClasses[] = $sk->getPageClasses( $this->getTitle() );
                $bodyClasses[] = 'skin-' . Sanitizer::escapeClass( $sk->getSkinName() );
                $bodyClasses[] =
@@ -2701,9 +2702,9 @@ class OutputPage extends ContextSource {
                $sk->addToBodyAttributes( $this, $bodyAttrs );
                Hooks::run( 'OutputPageBodyAttributes', [ $this, $sk, &$bodyAttrs ] );
 
-               $ret .= Html::openElement( 'body', $bodyAttrs ) . "\n";
+               $pieces[] = Html::openElement( 'body', $bodyAttrs );
 
-               return $ret;
+               return WrappedStringList::join( "\n", $pieces );
        }
 
        /**
@@ -2784,6 +2785,17 @@ class OutputPage extends ContextSource {
                                continue;
                        }
 
+                       if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
+                               if ( $module->getType() !== ResourceLoaderModule::LOAD_STYLES ) {
+                                       $logger = $resourceLoader->getLogger();
+                                       $logger->debug( 'Unexpected general module "{module}" in styles queue.', [
+                                               'module' => $name,
+                                       ] );
+                               } else {
+                                       $links['states'][$name] = 'ready';
+                               }
+                       }
+
                        $sortedModules[$module->getSource()][$module->getGroup()][$name] = $module;
                }
 
@@ -2904,7 +2916,7 @@ class OutputPage extends ContextSource {
        /**
         * Build html output from an array of links from makeResourceLoaderLink.
         * @param array $links
-        * @return string HTML
+        * @return string|WrappedStringList HTML
         */
        protected static function getHtmlFromLoaderLinks( array $links ) {
                $html = [];
@@ -2920,7 +2932,7 @@ class OutputPage extends ContextSource {
                // Filter out empty values
                $html = array_filter( $html, 'strlen' );
 
-               if ( count( $states ) ) {
+               if ( $states ) {
                        array_unshift( $html, ResourceLoader::makeInlineScript(
                                ResourceLoader::makeLoaderStateScript( $states )
                        ) );
@@ -2940,25 +2952,23 @@ class OutputPage extends ContextSource {
        }
 
        /**
-        * <script src="..."> tags for "<head>". This is the startup module
+        * <script src="..."> tags for "<head>".This is the startup module
         * and other modules marked with position 'top'.
         *
-        * @return string HTML fragment
+        * @return string|WrappedStringList HTML
         */
        function getExternalHeadScripts() {
-               $links = [];
-
                // Startup - this provides the client with the module
                // manifest and loads jquery and mediawiki base modules
+               $links = [];
                $links[] = $this->makeResourceLoaderLink( 'startup', ResourceLoaderModule::TYPE_SCRIPTS );
-
                return self::getHtmlFromLoaderLinks( $links );
        }
 
        /**
-        * <script>...</script> tags to put in "<head>".
+        * Inline "<script>" tags to put in "<head>".
         *
-        * @return string HTML fragment
+        * @return string|WrappedStringList HTML
         */
        function getInlineHeadScripts() {
                $links = [];
@@ -3018,7 +3028,7 @@ class OutputPage extends ContextSource {
         *
         * @param bool $unused Previously used to let this method change its output based
         *  on whether it was called by getExternalHeadScripts() or getBottomScripts().
-        * @return string
+        * @return string|WrappedStringList HTML
         */
        function getScriptsForBottomQueue( $unused = null ) {
                // Scripts "only" requests marked for bottom inclusion
@@ -3617,10 +3627,9 @@ class OutputPage extends ContextSource {
        }
 
        /**
-        * Build a set of "<link>" elements for the stylesheets specified in the $this->styles array.
-        * These will be applied to various media & IE conditionals.
+        * Build a set of "<link>" elements for stylesheets specified in the $this->styles array.
         *
-        * @return string
+        * @return string|WrappedStringList HTML
         */
        public function buildCssLinks() {
                global $wgContLang;
@@ -3722,7 +3731,9 @@ class OutputPage extends ContextSource {
                }
 
                // Add stuff in $otherTags (previewed user CSS if applicable)
-               return self::getHtmlFromLoaderLinks( $links ) . implode( '', $otherTags );
+               $links[] = implode( '', $otherTags );
+
+               return self::getHtmlFromLoaderLinks( $links );
        }
 
        /**
diff --git a/includes/Pingback.php b/includes/Pingback.php
new file mode 100644 (file)
index 0000000..f633029
--- /dev/null
@@ -0,0 +1,247 @@
+<?php
+/**
+ * Send information about this MediaWiki instance to MediaWiki.org.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+use Psr\Log\LoggerInterface;
+use MediaWiki\Logger\LoggerFactory;
+
+/**
+ * Send information about this MediaWiki instance to MediaWiki.org.
+ *
+ * @since 1.28
+ */
+class Pingback {
+
+       /**
+        * @var int Revision ID of the JSON schema that describes the pingback
+        *   payload. The schema lives on MetaWiki, at
+        *   <https://meta.wikimedia.org/wiki/Schema:MediaWikiPingback>.
+        */
+       const SCHEMA_REV = 15781718;
+
+       /** @var LoggerInterface */
+       protected $logger;
+
+       /** @var Config */
+       protected $config;
+
+       /** @var string updatelog key (also used as cache/db lock key) */
+       protected $key;
+
+       /** @var string Randomly-generated identifier for this wiki */
+       protected $id;
+
+       /**
+        * @param Config $config
+        * @param LoggerInterface $logger
+        */
+       public function __construct( Config $config = null, LoggerInterface $logger = null ) {
+               $this->config = $config ?: RequestContext::getMain()->getConfig();
+               $this->logger = $logger ?: LoggerFactory::getInstance( __CLASS__ );
+               $this->key = 'Pingback-' . $this->config->get( 'Version' );
+       }
+
+       /**
+        * Should a pingback be sent?
+        * @return bool
+        */
+       private function shouldSend() {
+               return $this->config->get( 'Pingback' ) && !$this->checkIfSent();
+       }
+
+       /**
+        * Has a pingback already been sent for this MediaWiki version?
+        * @return bool
+        */
+       private function checkIfSent() {
+               $dbr = wfGetDB( DB_SLAVE );
+               $sent = $dbr->selectField(
+                       'updatelog', '1', [ 'ul_key' => $this->key ], __METHOD__ );
+               return $sent !== false;
+       }
+
+       /**
+        * Record the fact that we have sent a pingback for this MediaWiki version,
+        * to ensure we don't submit data multiple times.
+        */
+       private function markSent() {
+               $dbw = wfGetDB( DB_MASTER );
+               return $dbw->insert(
+                       'updatelog', [ 'ul_key' => $this->key ], __METHOD__, 'IGNORE' );
+       }
+
+       /**
+        * Acquire lock for sending a pingback
+        *
+        * This ensures only one thread can attempt to send a pingback at any given
+        * time and that we wait an hour before retrying failed attempts.
+        *
+        * @return bool Whether lock was acquired
+        */
+       private function acquireLock() {
+               $cache = ObjectCache::getLocalClusterInstance();
+               if ( !$cache->add( $this->key, 1, 60 * 60 ) ) {
+                       return false;  // throttled
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               if ( !$dbw->lock( $this->key, __METHOD__, 0 ) ) {
+                       return false;  // already in progress
+               }
+
+               return true;
+       }
+
+       /**
+        * Collect basic data about this MediaWiki installation and return it
+        * as an associative array conforming to the Pingback schema on MetaWiki
+        * (<https://meta.wikimedia.org/wiki/Schema:MediaWikiPingback>).
+        *
+        * @return array
+        */
+       private function getData() {
+               $event = [
+                       'database'   => $this->config->get( 'DBtype' ),
+                       'MediaWiki'  => $this->config->get( 'Version' ),
+                       'PHP'        => PHP_VERSION,
+                       'OS'         => PHP_OS . ' ' . php_uname( 'r' ),
+                       'arch'       => PHP_INT_SIZE === 8 ? 64 : 32,
+                       'machine'    => php_uname( 'm' ),
+               ];
+
+               if ( isset( $_SERVER['SERVER_SOFTWARE'] ) ) {
+                       $event['serverSoftware'] = $_SERVER['SERVER_SOFTWARE'];
+               }
+
+               $limit = ini_get( 'memory_limit' );
+               if ( $limit && $limit != -1 ) {
+                       $event['memoryLimit'] = $limit;
+               }
+
+               return [
+                       'schema'           => 'MediaWikiPingback',
+                       'revision'         => self::SCHEMA_REV,
+                       'wiki'             => $this->getOrCreatePingbackId(),
+                       'event'            => $event,
+               ];
+       }
+
+       /**
+        * Get a unique, stable identifier for this wiki
+        *
+        * If the identifier does not already exist, create it and save it in the
+        * database. The identifier is randomly-generated.
+        *
+        * @return string 32-character hex string
+        */
+       private function getOrCreatePingbackId() {
+               if ( !$this->id ) {
+                       $id = wfGetDB( DB_SLAVE )->selectField(
+                               'updatelog', 'ul_value', [ 'ul_key' => 'PingBack' ] );
+
+                       if ( $id == false ) {
+                               $id = MWCryptRand::generateHex( 32 );
+                               $dbw = wfGetDB( DB_MASTER );
+                               $dbw->insert(
+                                       'updatelog',
+                                       [ 'ul_key' => 'PingBack', 'ul_value' => $id ],
+                                       __METHOD__,
+                                       'IGNORE'
+                               );
+
+                               if ( !$dbw->affectedRows() ) {
+                                       $id = $dbw->selectField(
+                                               'updatelog', 'ul_value', [ 'ul_key' => 'PingBack' ] );
+                               }
+                       }
+
+                       $this->id = $id;
+               }
+
+               return $this->id;
+       }
+
+       /**
+        * Serialize pingback data and send it to MediaWiki.org via a POST
+        * to its event beacon endpoint.
+        *
+        * The data encoding conforms to the expectations of EventLogging,
+        * a software suite used by the Wikimedia Foundation for logging and
+        * processing analytic data.
+        *
+        * Compare:
+        * <https://github.com/wikimedia/mediawiki-extensions-EventLogging/
+        *   blob/7e5fe4f1ef/includes/EventLogging.php#L32-L74>
+        *
+        * @param data Pingback data as an associative array
+        * @return bool true on success, false on failure
+        */
+       private function postPingback( array $data ) {
+               $json = FormatJson::encode( $data );
+               $queryString = rawurlencode( str_replace( ' ', '\u0020', $json ) ) . ';';
+               $url = 'https://www.mediawiki.org/beacon/event?' . $queryString;
+               return Http::post( $url ) !== false;
+       }
+
+       /**
+        * Send information about this MediaWiki instance to MediaWiki.org.
+        *
+        * The data is structured and serialized to match the expectations of
+        * EventLogging, a software suite used by the Wikimedia Foundation for
+        * logging and processing analytic data.
+        *
+        * Compare:
+        * <https://github.com/wikimedia/mediawiki-extensions-EventLogging/
+        *   blob/7e5fe4f1ef/includes/EventLogging.php#L32-L74>
+        *
+        * The schema for the data is located at:
+        * <https://meta.wikimedia.org/wiki/Schema:MediaWikiPingback>
+        */
+       public function sendPingback() {
+               if ( !$this->acquireLock() ) {
+                       $this->logger->debug( __METHOD__ . ": couldn't acquire lock" );
+                       return false;
+               }
+
+               $data = $this->getData();
+               if ( !$this->postPingback( $data ) ) {
+                       $this->logger->warning( __METHOD__ . ": failed to send pingback; check 'http' log" );
+                       return false;
+               }
+
+               $this->markSent();
+               $this->logger->debug( __METHOD__ . ": pingback sent OK ({$this->key})" );
+               return true;
+       }
+
+       /**
+        * Schedule a deferred callable that will check if a pingback should be
+        * sent and (if so) proceed to send it.
+        */
+       public static function schedulePingback() {
+               DeferredUpdates::addCallableUpdate( function () {
+                       $instance = new Pingback;
+                       if ( $instance->shouldSend() ) {
+                               $instance->sendPingback();
+                       }
+               } );
+       }
+}
index 5c4302e..eda8989 100644 (file)
@@ -1110,7 +1110,7 @@ class Revision implements IDBAccessObject {
                if ( !$this->mContentModel ) {
                        $title = $this->getTitle();
                        if ( $title ) {
-                               $this->mContentModel = $title->getContentModel();
+                               $this->mContentModel = ContentHandler::getDefaultModelFor( $title );
                        } else {
                                $this->mContentModel = CONTENT_MODEL_WIKITEXT;
                        }
@@ -1455,7 +1455,7 @@ class Revision implements IDBAccessObject {
                                        . "revision's page!" );
                        }
 
-                       $defaultModel = $title->getContentModel();
+                       $defaultModel = ContentHandler::getDefaultModelFor( $title );
                        $defaultFormat = ContentHandler::getForModelID( $defaultModel )->getDefaultFormat();
 
                        $row['rev_content_model'] = ( $model === $defaultModel ) ? null : $model;
index d321e9f..8f1fc99 100644 (file)
@@ -381,14 +381,17 @@ class Sanitizer {
                                'kbd', 'samp', 'data', 'time', 'mark'
                        ];
                        $htmlsingle = [
-                               'br', 'wbr', 'hr', 'li', 'dt', 'dd'
-                       ];
-                       $htmlsingleonly = [ # Elements that cannot have close tags
-                               'br', 'wbr', 'hr'
+                               'br', 'wbr', 'hr', 'li', 'dt', 'dd', 'meta', 'link'
                        ];
 
-                       $htmlsingle[] = $htmlsingleonly[] = 'meta';
-                       $htmlsingle[] = $htmlsingleonly[] = 'link';
+                       # Elements that cannot have close tags. This is (not coincidentally)
+                       # also the list of tags for which the HTML 5 parsing algorithm
+                       # requires you to "acknowledge the token's self-closing flag", i.e.
+                       # a self-closing tag like <br/> is not an HTML 5 parse error only
+                       # for this list.
+                       $htmlsingleonly = [
+                               'br', 'wbr', 'hr', 'meta', 'link'
+                       ];
 
                        $htmlnest = [ # Tags that can be nested--??
                                'table', 'tr', 'td', 'th', 'div', 'blockquote', 'ol', 'ul',
@@ -450,10 +453,14 @@ class Sanitizer {
         * @param array|bool $args Arguments for the processing callback
         * @param array $extratags For any extra tags to include
         * @param array $removetags For any tags (default or extra) to exclude
+        * @param callable $warnCallback (Deprecated) Callback allowing the
+        *   addition of a tracking category when bad input is encountered.
+        *   DO NOT ADD NEW PARAMETERS AFTER $warnCallback, since it will be
+        *   removed shortly.
         * @return string
         */
        public static function removeHTMLtags( $text, $processCallback = null,
-               $args = [], $extratags = [], $removetags = []
+               $args = [], $extratags = [], $removetags = [], $warnCallback = null
        ) {
                extract( self::getRecognizedTagData( $extratags, $removetags ) );
 
@@ -540,6 +547,14 @@ class Sanitizer {
                                                        $badtag = true;
                                                #  Is it a self closed htmlpair ? (bug 5487)
                                                } elseif ( $brace == '/>' && isset( $htmlpairs[$t] ) ) {
+                                                       // Eventually we'll just remove the self-closing
+                                                       // slash, in order to be consistent with HTML5
+                                                       // semantics.
+                                                       // $brace = '>';
+                                                       // For now, let's just warn authors to clean up.
+                                                       if ( is_callable( $warnCallback ) ) {
+                                                               call_user_func_array( $warnCallback, [ 'deprecated-self-close-category' ] );
+                                                       }
                                                        $badtag = true;
                                                } elseif ( isset( $htmlsingleonly[$t] ) ) {
                                                        # Hack to force empty tag for unclosable elements
@@ -604,12 +619,29 @@ class Sanitizer {
                                                        call_user_func_array( $processCallback, [ &$params, $args ] );
                                                }
 
+                                               if ( $brace == '/>' && !( isset( $htmlsingle[$t] ) || isset( $htmlsingleonly[$t] ) ) ) {
+                                                       // Eventually we'll just remove the self-closing
+                                                       // slash, in order to be consistent with HTML5
+                                                       // semantics.
+                                                       // $brace = '>';
+                                                       // For now, let's just warn authors to clean up.
+                                                       if ( is_callable( $warnCallback ) ) {
+                                                               call_user_func_array( $warnCallback, [ 'deprecated-self-close-category' ] );
+                                                       }
+                                               }
                                                if ( !Sanitizer::validateTag( $params, $t ) ) {
                                                        $badtag = true;
                                                }
 
                                                $newparams = Sanitizer::fixTagAttributes( $params, $t );
                                                if ( !$badtag ) {
+                                                       if ( $brace === '/>' && !isset( $htmlsingleonly[$t] ) ) {
+                                                               # Interpret self-closing tags as empty tags even when
+                                                               # HTML 5 would interpret them as start tags. Such input
+                                                               # is commonly seen on Wikimedia wikis with this intention.
+                                                               $brace = "></$t>";
+                                                       }
+
                                                        $rest = str_replace( '>', '&gt;', $rest );
                                                        $text .= "<$slash$t$newparams$brace$rest";
                                                        continue;
@@ -1028,12 +1060,14 @@ class Sanitizer {
         * - Double attributes are discarded
         * - Unsafe style attributes are discarded
         * - Prepends space if there are attributes.
+        * - (Optionally) Sorts attributes by name.
         *
         * @param string $text
         * @param string $element
+        * @param bool $sorted Whether to sort the attributes (default: false)
         * @return string
         */
-       static function fixTagAttributes( $text, $element ) {
+       static function fixTagAttributes( $text, $element, $sorted = false ) {
                if ( trim( $text ) == '' ) {
                        return '';
                }
@@ -1041,6 +1075,10 @@ class Sanitizer {
                $decoded = Sanitizer::decodeTagAttributes( $text );
                $stripped = Sanitizer::validateTagAttributes( $decoded, $element );
 
+               if ( $sorted ) {
+                       ksort( $stripped );
+               }
+
                return Sanitizer::safeEncodeTagAttributes( $stripped );
        }
 
index 9ee4236..d4f16ee 100644 (file)
@@ -166,7 +166,8 @@ return [
 
        'LinkRendererFactory' => function( MediaWikiServices $services ) {
                return new LinkRendererFactory(
-                       $services->getTitleFormatter()
+                       $services->getTitleFormatter(),
+                       $services->getLinkCache()
                );
        },
 
index cb1bd71..6c5de90 100644 (file)
@@ -705,7 +705,6 @@ $ps_globals = Profiler::instance()->scopedProfileIn( $fname . '-globals' );
  * @var Language $wgContLang
  */
 $wgContLang = Language::factory( $wgLanguageCode );
-$wgContLang->initEncoding();
 $wgContLang->initContLang();
 
 // Now that variant lists may be available...
@@ -872,6 +871,10 @@ if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
        unset( $sessionUser );
 }
 
+if ( !$wgCommandLineMode ) {
+       Pingback::schedulePingback();
+}
+
 wfDebug( "Fully initialised\n" );
 $wgFullyInitialised = true;
 
index 1a92fb2..5b9bdfa 100644 (file)
@@ -565,17 +565,6 @@ class SiteConfiguration {
                return $multi ? $res : current( $res );
        }
 
-       /**
-        * Returns true if the given vhost is handled locally.
-        *
-        * @deprecated since 1.25; check if the host is in $wgLocalVirtualHosts instead.
-        * @param string $vhost
-        * @return bool
-        */
-       public function isLocalVHost( $vhost ) {
-               return in_array( $vhost, $this->localVHosts );
-       }
-
        /**
         * Merge multiple arrays together.
         * On encountering duplicate keys, merge the two, but ONLY if they're arrays.
index 8d0b8f1..0fc7980 100644 (file)
  * Functions related to the output of file content
  */
 class StreamFile {
-       const READY_STREAM = 1;
-       const NOT_MODIFIED = 2;
+       // Do not send any HTTP headers unless requested by caller (e.g. body only)
+       const STREAM_HEADLESS = 1;
+       // Do not try to tear down any PHP output buffers
+       const STREAM_ALLOW_OB = 2;
 
        /**
         * Stream a file to the browser, adding all the headings and fun stuff.
@@ -33,107 +35,183 @@ class StreamFile {
         * and Content-Disposition.
         *
         * @param string $fname Full name and path of the file to stream
-        * @param array $headers Any additional headers to send
+        * @param array $headers Any additional headers to send if the file exists
         * @param bool $sendErrors Send error messages if errors occur (like 404)
+        * @param array $optHeaders HTTP request header map (e.g. "range") (use lowercase keys)
+        * @param integer $flags Bitfield of STREAM_* constants
         * @throws MWException
         * @return bool Success
         */
-       public static function stream( $fname, $headers = [], $sendErrors = true ) {
+       public static function stream(
+               $fname, $headers = [], $sendErrors = true, $optHeaders = [], $flags = 0
+       ) {
+               $section = new ProfileSection( __METHOD__ );
 
                if ( FileBackend::isStoragePath( $fname ) ) { // sanity
                        throw new MWException( __FUNCTION__ . " given storage path '$fname'." );
                }
 
-               MediaWiki\suppressWarnings();
-               $stat = stat( $fname );
-               MediaWiki\restoreWarnings();
-
-               $res = self::prepareForStream( $fname, $stat, $headers, $sendErrors );
-               if ( $res == self::NOT_MODIFIED ) {
-                       $ok = true; // use client cache
-               } elseif ( $res == self::READY_STREAM ) {
-                       $ok = readfile( $fname );
-               } else {
-                       $ok = false; // failed
+               // Don't stream it out as text/html if there was a PHP error
+               if ( ( ( $flags & self::STREAM_HEADLESS ) == 0 || $headers ) && headers_sent() ) {
+                       echo "Headers already sent, terminating.\n";
+                       return false;
                }
 
-               return $ok;
-       }
+               $headerFunc = ( $flags & self::STREAM_HEADLESS )
+                       ? function ( $header ) {
+                                // no-op
+                       }
+                       : function ( $header ) {
+                               is_int( $header ) ? HttpStatus::header( $header ) : header( $header );
+                       };
+
+               MediaWiki\suppressWarnings();
+               $info = stat( $fname );
+               MediaWiki\restoreWarnings();
 
-       /**
-        * Call this function used in preparation before streaming a file.
-        * This function does the following:
-        * (a) sends Last-Modified, Content-type, and Content-Disposition headers
-        * (b) cancels any PHP output buffering and automatic gzipping of output
-        * (c) sends Content-Length header based on HTTP_IF_MODIFIED_SINCE check
-        *
-        * @param string $path Storage path or file system path
-        * @param array|bool $info File stat info with 'mtime' and 'size' fields
-        * @param array $headers Additional headers to send
-        * @param bool $sendErrors Send error messages if errors occur (like 404)
-        * @return int|bool READY_STREAM, NOT_MODIFIED, or false on failure
-        */
-       public static function prepareForStream(
-               $path, $info, $headers = [], $sendErrors = true
-       ) {
                if ( !is_array( $info ) ) {
                        if ( $sendErrors ) {
-                               HttpStatus::header( 404 );
-                               header( 'Cache-Control: no-cache' );
-                               header( 'Content-Type: text/html; charset=utf-8' );
-                               $encFile = htmlspecialchars( $path );
-                               $encScript = htmlspecialchars( $_SERVER['SCRIPT_NAME'] );
-                               echo "<html><body>
-                                       <h1>File not found</h1>
-                                       <p>Although this PHP script ($encScript) exists, the file requested for output
-                                       ($encFile) does not.</p>
-                                       </body></html>
-                                       ";
+                               self::send404Message( $fname, $flags );
                        }
                        return false;
                }
 
-               // Sent Last-Modified HTTP header for client-side caching
-               header( 'Last-Modified: ' . wfTimestamp( TS_RFC2822, $info['mtime'] ) );
+               // Send Last-Modified HTTP header for client-side caching
+               $headerFunc( 'Last-Modified: ' . wfTimestamp( TS_RFC2822, $info['mtime'] ) );
 
-               // Cancel output buffering and gzipping if set
-               wfResetOutputBuffers();
+               if ( ( $flags & self::STREAM_ALLOW_OB ) == 0 ) {
+                       // Cancel output buffering and gzipping if set
+                       wfResetOutputBuffers();
+               }
 
-               $type = self::contentTypeFromPath( $path );
+               $type = self::contentTypeFromPath( $fname );
                if ( $type && $type != 'unknown/unknown' ) {
-                       header( "Content-type: $type" );
+                       $headerFunc( "Content-type: $type" );
                } else {
                        // Send a content type which is not known to Internet Explorer, to
                        // avoid triggering IE's content type detection. Sending a standard
                        // unknown content type here essentially gives IE license to apply
                        // whatever content type it likes.
-                       header( 'Content-type: application/x-wiki' );
+                       $headerFunc( 'Content-type: application/x-wiki' );
                }
 
-               // Don't stream it out as text/html if there was a PHP error
-               if ( headers_sent() ) {
-                       echo "Headers already sent, terminating.\n";
-                       return false;
+               // Don't send if client has up to date cache
+               if ( isset( $optHeaders['if-modified-since'] ) ) {
+                       $modsince = preg_replace( '/;.*$/', '', $optHeaders['if-modified-since'] );
+                       if ( wfTimestamp( TS_UNIX, $info['mtime'] ) <= strtotime( $modsince ) ) {
+                               ini_set( 'zlib.output_compression', 0 );
+                               $headerFunc( 304 );
+                               return true; // ok
+                       }
                }
 
                // Send additional headers
                foreach ( $headers as $header ) {
-                       header( $header );
+                       header( $header ); // always use header(); specifically requested
                }
 
-               // Don't send if client has up to date cache
-               if ( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
-                       $modsince = preg_replace( '/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
-                       if ( wfTimestamp( TS_UNIX, $info['mtime'] ) <= strtotime( $modsince ) ) {
-                               ini_set( 'zlib.output_compression', 0 );
-                               HttpStatus::header( 304 );
-                               return self::NOT_MODIFIED; // ok
+               if ( isset( $optHeaders['range'] ) ) {
+                       $range = self::parseRange( $optHeaders['range'], $info['size'] );
+                       if ( is_array( $range ) ) {
+                               $headerFunc( 206 );
+                               $headerFunc( 'Content-Length: ' . $range[2] );
+                               $headerFunc( "Content-Range: bytes {$range[0]}-{$range[1]}/{$info['size']}" );
+                       } elseif ( $range === 'invalid' ) {
+                               if ( $sendErrors ) {
+                                       $headerFunc( 416 );
+                                       $headerFunc( 'Cache-Control: no-cache' );
+                                       $headerFunc( 'Content-Type: text/html; charset=utf-8' );
+                                       $headerFunc( 'Content-Range: bytes */' . $info['size'] );
+                               }
+                               return false;
+                       } else { // unsupported Range request (e.g. multiple ranges)
+                               $range = null;
+                               $headerFunc( 'Content-Length: ' . $info['size'] );
+                       }
+               } else {
+                       $range = null;
+                       $headerFunc( 'Content-Length: ' . $info['size'] );
+               }
+
+               if ( is_array( $range ) ) {
+                       $handle = fopen( $fname, 'rb' );
+                       if ( $handle ) {
+                               $ok = true;
+                               fseek( $handle, $range[0] );
+                               $remaining = $range[2];
+                               while ( $remaining > 0 && $ok ) {
+                                       $bytes = min( $remaining, 8 * 1024 );
+                                       $data = fread( $handle, $bytes );
+                                       $remaining -= $bytes;
+                                       $ok = ( $data !== false );
+                                       print $data;
+                               }
+                       } else {
+                               return false;
                        }
+               } else {
+                       return readfile( $fname ) !== false; // faster
                }
 
-               header( 'Content-Length: ' . $info['size'] );
+               return true;
+       }
+
+       /**
+        * Send out a standard 404 message for a file
+        *
+        * @param string $fname Full name and path of the file to stream
+        * @param integer $flags Bitfield of STREAM_* constants
+        * @since 1.24
+        */
+       public static function send404Message( $fname, $flags = 0 ) {
+               if ( ( $flags & self::STREAM_HEADLESS ) == 0 ) {
+                       HttpStatus::header( 404 );
+                       header( 'Cache-Control: no-cache' );
+                       header( 'Content-Type: text/html; charset=utf-8' );
+               }
+               $encFile = htmlspecialchars( $fname );
+               $encScript = htmlspecialchars( $_SERVER['SCRIPT_NAME'] );
+               echo "<!DOCTYPE html><html><body>
+                       <h1>File not found</h1>
+                       <p>Although this PHP script ($encScript) exists, the file requested for output
+                       ($encFile) does not.</p>
+                       </body></html>
+                       ";
+       }
 
-               return self::READY_STREAM; // ok
+       /**
+        * Convert a Range header value to an absolute (start, end) range tuple
+        *
+        * @param string $range Range header value
+        * @param integer $size File size
+        * @return array|string Returns error string on failure (start, end, length)
+        * @since 1.24
+        */
+       public static function parseRange( $range, $size ) {
+               $m = [];
+               if ( preg_match( '#^bytes=(\d*)-(\d*)$#', $range, $m ) ) {
+                       list( , $start, $end ) = $m;
+                       if ( $start === '' && $end === '' ) {
+                               $absRange = [ 0, $size - 1 ];
+                       } elseif ( $start === '' ) {
+                               $absRange = [ $size - $end, $size - 1 ];
+                       } elseif ( $end === '' ) {
+                               $absRange = [ $start, $size - 1 ];
+                       } else {
+                               $absRange = [ $start, $end ];
+                       }
+                       if ( $absRange[0] >= 0 && $absRange[1] >= $absRange[0] ) {
+                               if ( $absRange[0] < $size ) {
+                                       $absRange[1] = min( $absRange[1], $size - 1 ); // stop at EOF
+                                       $absRange[2] = $absRange[1] - $absRange[0] + 1;
+                                       return $absRange;
+                               } elseif ( $absRange[0] == 0 && $size == 0 ) {
+                                       return 'unrecognized'; // the whole file should just be sent
+                               }
+                       }
+                       return 'invalid';
+               }
+               return 'unrecognized';
        }
 
        /**
index f291a69..8aa8cb7 100644 (file)
@@ -1773,12 +1773,13 @@ class Title implements LinkTarget {
         *
         * @param array $query
         * @param bool $query2
-        * @param string $proto Protocol to use; setting this will cause a full URL to be used
+        * @param string|int|bool $proto A PROTO_* constant on how the URL should be expanded,
+        *                               or false (default) for no expansion
         * @see self::getLocalURL for the arguments.
         * @return string The URL
         */
-       public function getLinkURL( $query = '', $query2 = false, $proto = PROTO_RELATIVE ) {
-               if ( $this->isExternal() || $proto !== PROTO_RELATIVE ) {
+       public function getLinkURL( $query = '', $query2 = false, $proto = false ) {
+               if ( $this->isExternal() || $proto !== false ) {
                        $ret = $this->getFullURL( $query, $query2, $proto );
                } elseif ( $this->getPrefixedText() === '' && $this->hasFragment() ) {
                        $ret = $this->getFragmentForURL();
@@ -4366,18 +4367,23 @@ class Title implements LinkTarget {
                        return true; // avoid gap locking if we know it's not there
                }
 
-               $method = __METHOD__;
-               $dbw = wfGetDB( DB_MASTER );
                $conds = $this->pageCond();
-               $dbw->onTransactionIdle( function () use ( $dbw, $conds, $method, $purgeTime ) {
-                       $dbTimestamp = $dbw->timestamp( $purgeTime ?: time() );
-                       $dbw->update(
-                               'page',
-                               [ 'page_touched' => $dbTimestamp ],
-                               $conds + [ 'page_touched < ' . $dbw->addQuotes( $dbTimestamp ) ],
-                               $method
-                       );
-               } );
+               DeferredUpdates::addUpdate(
+                       new AutoCommitUpdate(
+                               wfGetDB( DB_MASTER ),
+                               __METHOD__,
+                               function ( IDatabase $dbw, $fname ) use ( $conds, $purgeTime ) {
+                                       $dbTimestamp = $dbw->timestamp( $purgeTime ?: time() );
+                                       $dbw->update(
+                                               'page',
+                                               [ 'page_touched' => $dbTimestamp ],
+                                               $conds + [ 'page_touched < ' . $dbw->addQuotes( $dbTimestamp ) ],
+                                               $fname
+                                       );
+                               }
+                       ),
+                       DeferredUpdates::PRESEND
+               );
 
                return true;
        }
@@ -4553,10 +4559,10 @@ class Title implements LinkTarget {
         * @return bool
         */
        public function canUseNoindex() {
-               global $wgContentNamespaces, $wgExemptFromUserRobotsControl;
+               global $wgExemptFromUserRobotsControl;
 
                $bannedNamespaces = is_null( $wgExemptFromUserRobotsControl )
-                       ? $wgContentNamespaces
+                       ? MWNamespace::getContentNamespaces()
                        : $wgExemptFromUserRobotsControl;
 
                return !in_array( $this->mNamespace, $bannedNamespaces );
index 515fbfc..89ca50c 100644 (file)
@@ -719,28 +719,29 @@ class WatchedItemStore implements StatsdAwareInterface {
         */
        public function updateNotificationTimestamp( User $editor, LinkTarget $target, $timestamp ) {
                $dbw = $this->getConnection( DB_MASTER );
-               $res = $dbw->select( [ 'watchlist' ],
-                       [ 'wl_user' ],
+               $uids = $dbw->selectFieldValues(
+                       'watchlist',
+                       'wl_user',
                        [
                                'wl_user != ' . intval( $editor->getId() ),
                                'wl_namespace' => $target->getNamespace(),
                                'wl_title' => $target->getDBkey(),
                                'wl_notificationtimestamp IS NULL',
-                       ], __METHOD__
+                       ],
+                       __METHOD__
                );
+               $this->reuseConnection( $dbw );
 
-               $watchers = [];
-               foreach ( $res as $row ) {
-                       $watchers[] = intval( $row->wl_user );
-               }
-
+               $watchers = array_map( 'intval', $uids );
                if ( $watchers ) {
                        // Update wl_notificationtimestamp for all watching users except the editor
                        $fname = __METHOD__;
-                       $dbw->onTransactionIdle(
-                               function () use ( $dbw, $timestamp, $watchers, $target, $fname ) {
+                       DeferredUpdates::addCallableUpdate(
+                               function () use ( $timestamp, $watchers, $target, $fname ) {
                                        global $wgUpdateRowsPerQuery;
 
+                                       $dbw = $this->getConnection( DB_MASTER );
+
                                        $watchersChunks = array_chunk( $watchers, $wgUpdateRowsPerQuery );
                                        foreach ( $watchersChunks as $watchersChunk ) {
                                                $dbw->update( 'watchlist',
@@ -758,12 +759,12 @@ class WatchedItemStore implements StatsdAwareInterface {
                                                }
                                        }
                                        $this->uncacheLinkTarget( $target );
+
+                                       $this->reuseConnection( $dbw );
                                }
                        );
                }
 
-               $this->reuseConnection( $dbw );
-
                return $watchers;
        }
 
index 152a3d2..30efb3b 100644 (file)
@@ -567,19 +567,16 @@ class WebRequest {
         * Fetch a text string from the given array or return $default if it's not
         * set. Carriage returns are stripped from the text, and with some language
         * modules there is an input transliteration applied. This should generally
-        * be used for form "<textarea>" and "<input>" fields. Used for
-        * user-supplied freeform text input (for which input transformations may
-        * be required - e.g.  Esperanto x-coding).
+        * be used for form "<textarea>" and "<input>" fields, and for
+        * user-supplied freeform text input.
         *
         * @param string $name
         * @param string $default Optional
         * @return string
         */
        public function getText( $name, $default = '' ) {
-               global $wgContLang;
                $val = $this->getVal( $name, $default );
-               return str_replace( "\r\n", "\n",
-                       $wgContLang->recodeInput( $val ) );
+               return str_replace( "\r\n", "\n", $val );
        }
 
        /**
index 458c207..90b76e3 100644 (file)
@@ -89,26 +89,12 @@ class WebResponse {
         *     path: string, cookie path ($wgCookiePath)
         *     secure: bool, secure attribute ($wgCookieSecure)
         *     httpOnly: bool, httpOnly attribute ($wgCookieHttpOnly)
-        *     raw: bool, if true uses PHP's setrawcookie() instead of setcookie()
-        *   For backwards compatibility, if $options is not an array then it and
-        *   the following two parameters will be interpreted as values for
-        *   'prefix', 'domain', and 'secure'
         * @since 1.22 Replaced $prefix, $domain, and $forceSecure with $options
         */
        public function setCookie( $name, $value, $expire = 0, $options = [] ) {
                global $wgCookiePath, $wgCookiePrefix, $wgCookieDomain;
                global $wgCookieSecure, $wgCookieExpiration, $wgCookieHttpOnly;
 
-               if ( !is_array( $options ) ) {
-                       // Backwards compatibility
-                       $options = [ 'prefix' => $options ];
-                       if ( func_num_args() >= 5 ) {
-                               $options['domain'] = func_get_arg( 4 );
-                       }
-                       if ( func_num_args() >= 6 ) {
-                               $options['secure'] = func_get_arg( 5 );
-                       }
-               }
                $options = array_filter( $options, function ( $a ) {
                        return $a !== null;
                } ) + [
@@ -268,16 +254,6 @@ class FauxResponse extends WebResponse {
                global $wgCookiePath, $wgCookiePrefix, $wgCookieDomain;
                global $wgCookieSecure, $wgCookieExpiration, $wgCookieHttpOnly;
 
-               if ( !is_array( $options ) ) {
-                       // Backwards compatibility
-                       $options = [ 'prefix' => $options ];
-                       if ( func_num_args() >= 5 ) {
-                               $options['domain'] = func_get_arg( 4 );
-                       }
-                       if ( func_num_args() >= 6 ) {
-                               $options['secure'] = func_get_arg( 5 );
-                       }
-               }
                $options = array_filter( $options, function ( $a ) {
                        return $a !== null;
                } ) + [
index 3572229..0e4c6e0 100644 (file)
@@ -208,7 +208,7 @@ class ApiLogin extends ApiBase {
 
                                // Deprecated hook
                                $injected_html = '';
-                               Hooks::run( 'UserLoginComplete', [ &$user, &$injected_html ] );
+                               Hooks::run( 'UserLoginComplete', [ &$user, &$injected_html, true ] );
 
                                $result['lguserid'] = intval( $user->getId() );
                                $result['lgusername'] = $user->getName();
index 8878729..592df53 100644 (file)
@@ -298,6 +298,12 @@ class ApiMain extends ApiBase {
                        return true;
                }
 
+               // Anonymous CORS
+               if ( $request->getVal( 'origin' ) === '*' ) {
+                       $this->lacksSameOriginSecurity = true;
+                       return true;
+               }
+
                // Header to be used from XMLHTTPRequest when the request might
                // otherwise be used for XSS.
                if ( $request->getHeader( 'Treat-as-Untrusted' ) !== false ) {
@@ -644,31 +650,49 @@ class ApiMain extends ApiBase {
                $request = $this->getRequest();
                $response = $request->response();
 
-               // Origin: header is a space-separated list of origins, check all of them
-               $originHeader = $request->getHeader( 'Origin' );
-               if ( $originHeader === false ) {
-                       $origins = [];
+               $matchOrigin = false;
+               $allowTiming = false;
+               $varyOrigin = true;
+
+               if ( $originParam === '*' ) {
+                       // Request for anonymous CORS
+                       $matchOrigin = true;
+                       $allowOrigin = '*';
+                       $allowCredentials = 'false';
+                       $varyOrigin = false; // No need to vary
                } else {
-                       $originHeader = trim( $originHeader );
-                       $origins = preg_split( '/\s+/', $originHeader );
-               }
+                       // Non-anonymous CORS, check we allow the domain
 
-               if ( !in_array( $originParam, $origins ) ) {
-                       // origin parameter set but incorrect
-                       // Send a 403 response
-                       $response->statusHeader( 403 );
-                       $response->header( 'Cache-Control: no-cache' );
-                       echo "'origin' parameter does not match Origin header\n";
+                       // Origin: header is a space-separated list of origins, check all of them
+                       $originHeader = $request->getHeader( 'Origin' );
+                       if ( $originHeader === false ) {
+                               $origins = [];
+                       } else {
+                               $originHeader = trim( $originHeader );
+                               $origins = preg_split( '/\s+/', $originHeader );
+                       }
 
-                       return false;
-               }
+                       if ( !in_array( $originParam, $origins ) ) {
+                               // origin parameter set but incorrect
+                               // Send a 403 response
+                               $response->statusHeader( 403 );
+                               $response->header( 'Cache-Control: no-cache' );
+                               echo "'origin' parameter does not match Origin header\n";
 
-               $config = $this->getConfig();
-               $matchOrigin = count( $origins ) === 1 && self::matchOrigin(
-                       $originParam,
-                       $config->get( 'CrossSiteAJAXdomains' ),
-                       $config->get( 'CrossSiteAJAXdomainExceptions' )
-               );
+                               return false;
+                       }
+
+                       $config = $this->getConfig();
+                       $matchOrigin = count( $origins ) === 1 && self::matchOrigin(
+                               $originParam,
+                               $config->get( 'CrossSiteAJAXdomains' ),
+                               $config->get( 'CrossSiteAJAXdomainExceptions' )
+                       );
+
+                       $allowOrigin = $originHeader;
+                       $allowCredentials = 'true';
+                       $allowTiming = $originHeader;
+               }
 
                if ( $matchOrigin ) {
                        $requestedMethod = $request->getHeader( 'Access-Control-Request-Method' );
@@ -692,10 +716,12 @@ class ApiMain extends ApiBase {
                                $response->header( 'Access-Control-Allow-Methods: POST, GET' );
                        }
 
-                       $response->header( "Access-Control-Allow-Origin: $originHeader" );
-                       $response->header( 'Access-Control-Allow-Credentials: true' );
+                       $response->header( "Access-Control-Allow-Origin: $allowOrigin" );
+                       $response->header( "Access-Control-Allow-Credentials: $allowCredentials" );
                        // http://www.w3.org/TR/resource-timing/#timing-allow-origin
-                       $response->header( "Timing-Allow-Origin: $originHeader" );
+                       if ( $allowTiming !== false ) {
+                               $response->header( "Timing-Allow-Origin: $allowTiming" );
+                       }
 
                        if ( !$preflight ) {
                                $response->header(
@@ -704,7 +730,10 @@ class ApiMain extends ApiBase {
                        }
                }
 
-               $this->getOutput()->addVaryHeader( 'Origin' );
+               if ( $varyOrigin ) {
+                       $this->getOutput()->addVaryHeader( 'Origin' );
+               }
+
                return true;
        }
 
index 64bb9ba..822369a 100644 (file)
@@ -68,35 +68,37 @@ class ApiPurge extends ApiBase {
 
                                        # Parse content; note that HTML generation is only needed if we want to cache the result.
                                        $content = $page->getContent( Revision::RAW );
-                                       $enableParserCache = $this->getConfig()->get( 'EnableParserCache' );
-                                       $p_result = $content->getParserOutput(
-                                               $title,
-                                               $page->getLatest(),
-                                               $popts,
-                                               $enableParserCache
-                                       );
-
-                                       # Logging to better see expensive usage patterns
-                                       if ( $forceRecursiveLinkUpdate ) {
-                                               LoggerFactory::getInstance( 'RecursiveLinkPurge' )->info(
-                                                       "Recursive link purge enqueued for {title}",
-                                                       [
-                                                               'user' => $this->getUser()->getName(),
-                                                               'title' => $title->getPrefixedText()
-                                                       ]
+                                       if ( $content ) {
+                                               $enableParserCache = $this->getConfig()->get( 'EnableParserCache' );
+                                               $p_result = $content->getParserOutput(
+                                                       $title,
+                                                       $page->getLatest(),
+                                                       $popts,
+                                                       $enableParserCache
                                                );
-                                       }
-
-                                       # Update the links tables
-                                       $updates = $content->getSecondaryDataUpdates(
-                                               $title, null, $forceRecursiveLinkUpdate, $p_result );
-                                       DataUpdate::runUpdates( $updates );
-
-                                       $r['linkupdate'] = true;
 
-                                       if ( $enableParserCache ) {
-                                               $pcache = ParserCache::singleton();
-                                               $pcache->save( $p_result, $page, $popts );
+                                               # Logging to better see expensive usage patterns
+                                               if ( $forceRecursiveLinkUpdate ) {
+                                                       LoggerFactory::getInstance( 'RecursiveLinkPurge' )->info(
+                                                               "Recursive link purge enqueued for {title}",
+                                                               [
+                                                                       'user' => $this->getUser()->getName(),
+                                                                       'title' => $title->getPrefixedText()
+                                                               ]
+                                                       );
+                                               }
+
+                                               # Update the links tables
+                                               $updates = $content->getSecondaryDataUpdates(
+                                                       $title, null, $forceRecursiveLinkUpdate, $p_result );
+                                               DataUpdate::runUpdates( $updates );
+
+                                               $r['linkupdate'] = true;
+
+                                               if ( $enableParserCache ) {
+                                                       $pcache = ParserCache::singleton();
+                                                       $pcache->save( $p_result, $page, $popts );
+                                               }
                                        }
                                } else {
                                        $error = $this->parseMsg( [ 'actionthrottledtext' ] );
index ed4d373..5eb86ab 100644 (file)
@@ -443,16 +443,13 @@ class ApiQuery extends ApiBase {
                }
 
                $exporter = new WikiExporter( $this->getDB() );
-               // WikiExporter writes to stdout, so catch its
-               // output with an ob
-               ob_start();
+               $sink = new DumpStringOutput;
+               $exporter->setOutputSink( $sink );
                $exporter->openStream();
                foreach ( $exportTitles as $title ) {
                        $exporter->pageByTitle( $title );
                }
                $exporter->closeStream();
-               $exportxml = ob_get_contents();
-               ob_end_clean();
 
                // Don't check the size of exported stuff
                // It's not continuable, so it would cause more
@@ -460,10 +457,10 @@ class ApiQuery extends ApiBase {
                if ( $this->mParams['exportnowrap'] ) {
                        $result->reset();
                        // Raw formatter will handle this
-                       $result->addValue( null, 'text', $exportxml, ApiResult::NO_SIZE_CHECK );
+                       $result->addValue( null, 'text', $sink, ApiResult::NO_SIZE_CHECK );
                        $result->addValue( null, 'mime', 'text/xml', ApiResult::NO_SIZE_CHECK );
                } else {
-                       $result->addValue( 'query', 'export', $exportxml, ApiResult::NO_SIZE_CHECK );
+                       $result->addValue( 'query', 'export', $sink, ApiResult::NO_SIZE_CHECK );
                        $result->addValue( 'query', ApiResult::META_BC_SUBELEMENTS, [ 'export' ] );
                }
        }
index f0fd2f4..63c95d3 100644 (file)
@@ -150,7 +150,6 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                 *              AND rc_timestamp < $end AND rc_namespace = $namespace
                 */
                $this->addTables( 'recentchanges' );
-               $index = [ 'recentchanges' => 'rc_timestamp' ]; // May change
                $this->addTimestampWhereRange( 'rc_timestamp', $params['dir'], $params['start'], $params['end'] );
 
                if ( !is_null( $params['continue'] ) ) {
@@ -246,7 +245,6 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                if ( !is_null( $params['user'] ) ) {
                        $this->addWhereFld( 'rc_user_text', $params['user'] );
-                       $index['recentchanges'] = 'rc_user_text';
                }
 
                if ( !is_null( $params['excludeuser'] ) ) {
@@ -362,7 +360,6 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                $this->token = $params['token'];
                $this->addOption( 'LIMIT', $params['limit'] + 1 );
-               $this->addOption( 'USE INDEX', $index );
 
                $count = 0;
                /* Perform the actual query. */
index cb8d938..95659e5 100644 (file)
@@ -567,12 +567,28 @@ class ApiUpload extends ApiBase {
                                $this->dieUsage( $msg, 'filetype-banned', 0, $extradata );
                                break;
                        case UploadBase::VERIFICATION_ERROR:
-                               $params = $verification['details'];
-                               $key = array_shift( $params );
-                               $msg = $this->msg( $key, $params )->inLanguage( 'en' )->useDatabase( false )->text();
-                               ApiResult::setIndexedTagName( $verification['details'], 'detail' );
-                               $this->dieUsage( "This file did not pass file verification: $msg", 'verification-error',
-                                       0, [ 'details' => $verification['details'] ] );
+                               $parsed = $this->parseMsg( $verification['details'] );
+                               $info = "This file did not pass file verification: {$parsed['info']}";
+                               if ( $verification['details'][0] instanceof IApiMessage ) {
+                                       $code = $parsed['code'];
+                               } else {
+                                       // For backwards-compatibility, all of the errors from UploadBase::verifyFile() are
+                                       // reported as 'verification-error', and the real error code is reported in 'details'.
+                                       $code = 'verification-error';
+                               }
+                               if ( $verification['details'][0] instanceof IApiMessage ) {
+                                       $msg = $verification['details'][0];
+                                       $details = array_merge( [ $msg->getKey() ], $msg->getParams() );
+                               } else {
+                                       $details = $verification['details'];
+                               }
+                               ApiResult::setIndexedTagName( $details, 'detail' );
+                               $data = [ 'details' => $details ];
+                               if ( isset( $parsed['data'] ) ) {
+                                       $data = array_merge( $data, $parsed['data'] );
+                               }
+
+                               $this->dieUsage( $info, $code, 0, $data );
                                break;
                        case UploadBase::HOOK_ABORTED:
                                if ( is_array( $verification['error'] ) ) {
diff --git a/includes/api/i18n/azb.json b/includes/api/i18n/azb.json
new file mode 100644 (file)
index 0000000..ca09cf6
--- /dev/null
@@ -0,0 +1,15 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Ilğım"
+               ]
+       },
+       "apihelp-main-param-action": "هانسی ایش گؤرولسون.",
+       "apihelp-main-param-requestid": "بۇرادا یازیلان هر میقدار جاوابا آرتیلاجاقدیر. ایستک‌لری فرقلندیرمه‌یه ایشلنه بیلر.",
+       "apihelp-block-param-nocreate": "حساب آچماغین قاباغینی آل.",
+       "apihelp-checktoken-param-token": "تِست اۆچون توکن.",
+       "apihelp-compare-param-fromtitle": "مۆقاییسه اۆچون ایلک باشلیق.",
+       "apihelp-delete-description": "بیر صفحه‌نی سیل.",
+       "apihelp-delete-param-unwatch": "صفحه‌نی ایزله‌دیکلر لیستیندن سیل.",
+       "apihelp-edit-description": "صفحه‌لری یارادیب دَییشدیر."
+}
index 3b5201a..c7bfb23 100644 (file)
@@ -15,7 +15,7 @@
        "apihelp-main-param-requestid": "Любое значэньне, пададзенае тут, будзе ўключанае ў адказ. Можа быць выкарыстанае для адрозьненьня запытаў.",
        "apihelp-main-param-servedby": "Уключае ў вынік назву сэрвэра, які апрацаваў запыт.",
        "apihelp-main-param-curtimestamp": "Уключае ў вынік пазнаку актуальнага часу.",
-       "apihelp-main-param-origin": "Пры звароце да API з дапамогай міждамэннага AJAX-запыту (CORS), выстаўце парамэтру значэньне зыходнага дамэну. Ён мусіць быць уключаны ў кожны папярэдні запыт і такім чынам мусіць быць часткай URI-запыту (ня цела POST). Ён мусіць супадаць з адной з крыніц у загалоўку <code>Origin</code>, павінна быць зададзена нешта кшталту <kbd>https://en.wikipedia.org</kbd> або <kbd>https://meta.wikimedia.org</kbd>. Калі парамэтар не супадае з загалоўкам <code>Origin</code>, будзе вернуты адказ з кодам памылкі 403. Калі парамэтар супадае з загалоўкам <code>Origin</code> і крыніца знаходзіцца ў белым сьпісе, будзе выстаўлены загаловак <code>Access-Control-Allow-Origin</code>.",
+       "apihelp-main-param-origin": "Пры звароце да API з дапамогай міждамэннага AJAX-запыту (CORS), выстаўце парамэтру значэньне зыходнага дамэну. Ён мусіць быць уключаны ў кожны папярэдні запыт і такім чынам мусіць быць часткай URI-запыту (ня цела POST).\n\nДля аўтэнтыфікаваных запытаў ён мусіць супадаць з адной з крыніц у загалоўку <code>Origin</code>, павінна быць зададзена нешта кшталту <kbd>https://en.wikipedia.org</kbd> або <kbd>https://meta.wikimedia.org</kbd>. Калі парамэтар не супадае з загалоўкам <code>Origin</code>, будзе вернуты адказ з кодам памылкі 403. Калі парамэтар супадае з загалоўкам <code>Origin</code> і крыніца знаходзіцца ў белым сьпісе, будуць выстаўленыя загалоўкі <code>Access-Control-Allow-Origin</code> і <code>Access-Control-Allow-Credentials</code>.\n\nДля неаўтэнтыфікаваных запытаў выстаўце значэньне <kbd>*</kbd>. Гэта прывядзе да выстаўленьня загалоўку <code>Access-Control-Allow-Origin</code>, але <code>Access-Control-Allow-Credentials</code> будзе мець значэньне <code>false</code> і ўсе зьвесткі пра карыстальніка будуць абмежаваныя.",
        "apihelp-main-param-uselang": "Мова для выкарыстаньня ў перакладах паведамленьняў. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> з <kbd>siprop=languages</kbd> вяртае сьпіс кодаў мовы, або трэба вызначыць <kbd>user</kbd>, каб ужываць налады мовы цяперашняга карыстальніка, або вызначыць <kbd>content</kbd>, каб ужываць мову зьместу гэтай вікі.",
        "apihelp-block-description": "Блякаваньне ўдзельніка.",
        "apihelp-block-param-user": "Імя ўдзельніка, IP-адрас або IP-дыяпазон, якія вы хочаце заблякаваць.",
index 837e3f9..987231f 100644 (file)
@@ -9,7 +9,9 @@
                        "Fitoschido"
                ]
        },
+       "apihelp-main-param-action": "Quina acció realitzar.",
        "apihelp-main-param-format": "El format de la sortida.",
+       "apihelp-main-param-curtimestamp": "Inclou la marca horària actual en el resultat.",
        "apihelp-block-description": "Bloca un usuari.",
        "apihelp-block-param-reason": "Raó del blocatge.",
        "apihelp-block-param-nocreate": "Evita la creació de comptes.",
index 8437abb..605fcf5 100644 (file)
@@ -23,7 +23,7 @@
        "apihelp-main-param-requestid": "Libovolná zde uvedená hodnota bude zahrnuta v odpovědi. Lze použít pro rozlišení požadavků.",
        "apihelp-main-param-servedby": "Zahrnout do odpovědi název hostitele, který požadavek obsloužil.",
        "apihelp-main-param-curtimestamp": "Zahrnout do odpovědi aktuální časové razítko.",
-       "apihelp-main-param-origin": "Pokud k API přistupujete pomocí mezidoménového AJAXového požadavku (CORS), nastavte tento parametr na doménu původu. Musí být součástí všech předběžných požadavků, takže musí být součástí URI požadavku (nikoli těla POSTu). Hodnota musí přesně odpovídat jednomu z původů v hlavičce <code>Origin</code>, takže musí být nastavena na něco jako <kbd>https://en.wikipedia.org</kbd> nebo <kbd>https://meta.wikimedia.org</kbd>. Pokud parametr neodpovídá hlavičce <code>Origin</code>, bude vrácena odpověď 403. Pokud parametr odpovídá hlavičce <code>Origin</code> a tento původ je na bílé listině, bude nastavena hlavička <code>Access-Control-Allow-Origin</code>.",
+       "apihelp-main-param-origin": "Pokud k API přistupujete pomocí mezidoménového AJAXového požadavku (CORS), nastavte tento parametr na doménu původu. Musí být součástí všech předběžných požadavků, takže musí být součástí URI požadavku (nikoli těla POSTu).\n\nU ověřených požadavků hodnota musí přesně odpovídat jednomu z původů v hlavičce <code>Origin</code>, takže musí být nastavena na něco jako <kbd>https://en.wikipedia.org</kbd> nebo <kbd>https://meta.wikimedia.org</kbd>. Pokud parametr neodpovídá hlavičce <code>Origin</code>, bude vrácena odpověď 403. Pokud parametr odpovídá hlavičce <code>Origin</code> a tento původ je na bílé listině, hlavičky <code>Access-Control-Allow-Origin</code> a <code>Access-Control-Allow-Credentials</code>budou nastaveny.\n\nU neověřených požadavků specifikujte hodnotu <kbd>*</kbd>. To pomůže nastavit hlavičku <code>Access-Control-Allow-Origin</code>, ale hlavička <code>Access-Control-Allow-Credentials</code> bude <code>false</code> a všechna data uživatelů budou omezena.",
        "apihelp-main-param-uselang": "Jazyk, který se má použít pro překlad hlášení. Pomocí <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> se <kbd>siprop=languages</kbd> získáte seznam jazykových kódů nebo zadejte „<kbd>user</kbd>“ pro použití předvoleného jazyka aktuálního uživatele či „<kbd>content</kbd>“ pro použití jazyka obsahu této wiki.",
        "apihelp-block-description": "Zablokovat uživatele.",
        "apihelp-block-param-user": "Uživatelské jméno, IP adresa nebo rozsah IP adres, které chcete zablokovat.",
index ff4b499..dba5479 100644 (file)
@@ -29,7 +29,7 @@
        "apihelp-main-param-requestid": "Der angegebene Wert wird mit in die Antwort aufgenommen und kann zur Unterscheidung von Anfragen verwendet werden.",
        "apihelp-main-param-servedby": "Namen des bearbeitenden Hosts mit zurückgeben.",
        "apihelp-main-param-curtimestamp": "Aktuellen Zeitstempel mit zurückgeben.",
-       "apihelp-main-param-origin": "Beim Zugriff auf die API mittels Cross-Domain-AJAX-Anfrage (CORS) ist dieser Parameter auf die veranlassende Domain zu setzen. Er muss in jedem Pre-Flight-Request angegeben werden und deshalb ein Teil der Anfrage-URI sein (nicht des POST-Bodys). Er muss genau einer der Angaben im <code>Origin</code>-Header entsprechen, d.&nbsp;h. er muss auf etwas wie <kbd>https://de.wikipedia.org</kbd> oder <kbd>https://meta.wikimedia.org</kbd> gesetzt werden. Falls dieser Parameter nicht mit dem <code>Origin</code>-Header übereinstimmt, wird eine 403-Antwort zurückgegeben. Falls dieser Parameter dem <code>Origin</code>-Header entspricht und die Domain auf der Whitelist ist, wird ein <code>Access-Control-Allow-Origin</code>-Header gesetzt.",
+       "apihelp-main-param-origin": "Beim Zugriff auf die API mit einer Kreuz-Domain-AJAX-Anfrage (CORS) muss dies als entstehende Domäne festgelegt werden. Dies muss in jeder Vorfluganfrage mit eingeschlossen werden und deshalb ein Teil der Anfragen-URI sein (nicht des POST-Körpers).\n\nFür authentifizierte Anfragen muss dies exakt einem der Ursprünge im Header <code>Origin</code> entsprechen, so dass es auf etwas wie <kbd>https://de.wikipedia.org</kbd> oder <kbd>https://meta.wikimedia.org</kbd> festgelegt werden muss. Falls dieser Parameter nicht mit dem Header <code>Origin</code> übereinstimmt, wird eine 403-Antwort zurückgegeben. Falls dieser Parameter mit dem Header <code>Origin</code> übereinstimmt und der Ursprung weißgelistet ist, werden die Header <code>Access-Control-Allow-Origin</code> und <code>Access-Control-Allow-Credentials</code> festgelegt.\n\nGib für nicht authentifizierte Anfragen den Wert <kbd>*</kbd> an. Dies verursacht, dass der Header <code>Access-Control-Allow-Origin</code> festgelegt wird, aber <code>Access-Control-Allow-Credentials</code> wird <code>false</code> sein und alle benutzerspezifischen Daten werden beschränkt.",
        "apihelp-main-param-uselang": "Zu verwendende Sprache für Nachrichtenübersetzungen. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> mit <kbd>siprop=languages</kbd> gibt eine Liste der Sprachcodes zurück. Gib <kbd>user</kbd> zum Verwenden der aktuellen Benutzerspracheinstellung oder <kbd>content</kbd> an, um die Inhaltssprache des Wikis zu verwenden.",
        "apihelp-block-description": "Einen Benutzer sperren.",
        "apihelp-block-param-user": "Benutzername, IP-Adresse oder IP-Bereich, der gesperrt werden soll.",
index d2e070a..7892efa 100644 (file)
        "apihelp-block-param-reason": "Sebeba Bloqey",
        "apihelp-block-param-nocreate": "Hesab viraştişi bloqe ke.",
        "apihelp-checktoken-param-token": "Jetona test ke",
+       "apihelp-createaccount-description": "Yew Hesabê karberi yo newe vıraze",
        "apihelp-createaccount-param-name": "Nameyê karberi.",
+       "apihelp-createaccount-param-email": "E-postay karberi (keyfi)",
+       "apihelp-createaccount-param-realname": "Namey karberi yo raştay (keyfi)",
        "apihelp-delete-description": "Pele bestere.",
+       "apihelp-delete-example-simple": "<kbd>Main Page</kbd> besternê.",
        "apihelp-disabled-description": "Eno modul aktiv niyo.",
        "apihelp-edit-description": "Vıraze û pelan bıvurne.",
        "apihelp-edit-param-text": "Zerreki pele",
@@ -26,6 +30,8 @@
        "apihelp-emailuser-param-ccme": "Yew kopyaya nê posteyi mı rê bırışe.",
        "apihelp-expandtemplates-param-title": "Sernameyê pele.",
        "apihelp-expandtemplates-param-text": "Wikimetıni açarnê.",
+       "apihelp-expandtemplates-paramvalue-prop-wikitext": "Herabıyaye wikimetin",
+       "apihelp-feedcontributions-param-feedformat": "Formata warikerdışi",
        "apihelp-feedcontributions-param-hideminor": "Vuryayışanê werdiyan bınımne",
        "apihelp-feedcontributions-param-showsizediff": "Goreyê ebati ferqê versiyoni bıasne.",
        "apihelp-feedrecentchanges-param-hideminor": "Vurnayışanê qıckekan bınımne.",
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrey etiketi",
        "apihelp-feedrecentchanges-example-simple": "Vurnayışê peyênan bıvin",
        "apihelp-feedrecentchanges-example-30days": "Peyni vurnayışanê 30 raco bımosne",
+       "apihelp-filerevert-param-comment": "Mışewre bar ke",
        "apihelp-login-param-name": "Nameyê karberi.",
        "apihelp-login-param-password": "Parola.",
        "apihelp-login-param-domain": "Domain (optional).",
        "apihelp-login-example-login": "Dekew.",
        "apihelp-mergehistory-description": "Verorê pela yew ke",
        "apihelp-move-description": "Yew pele bere.",
+       "apihelp-move-param-noredirect": "Hetenayış mevıraz",
+       "apihelp-options-example-reset": "Terciha pêron reset ke",
+       "apihelp-options-example-change": "Tercihanê <kbd>skin</kbd> u <kbd>hideminor</kbd> bıvurnê",
        "apihelp-parse-example-page": "Peler analiz ke",
        "apihelp-parse-example-text": "Wikimetini analiz ke",
        "apihelp-parse-example-summary": "Xulasay analiz ke",
index 24b66ab..a8f0278 100644 (file)
@@ -16,7 +16,7 @@
        "apihelp-main-param-requestid": "Any value given here will be included in the response. May be used to distinguish requests.",
        "apihelp-main-param-servedby": "Include the hostname that served the request in the results.",
        "apihelp-main-param-curtimestamp": "Include the current timestamp in the result.",
-       "apihelp-main-param-origin": "When accessing the API using a cross-domain AJAX request (CORS), set this to the originating domain. This must be included in any pre-flight request, and therefore must be part of the request URI (not the POST body). This must match one of the origins in the <code>Origin</code> header exactly, so it has to be set to something like <kbd>https://en.wikipedia.org</kbd> or <kbd>https://meta.wikimedia.org</kbd>. If this parameter does not match the <code>Origin</code> header, a 403 response will be returned. If this parameter matches the <code>Origin</code> header and the origin is whitelisted, an <code>Access-Control-Allow-Origin</code> header will be set.",
+       "apihelp-main-param-origin": "When accessing the API using a cross-domain AJAX request (CORS), set this to the originating domain. This must be included in any pre-flight request, and therefore must be part of the request URI (not the POST body).\n\nFor authenticated requests, this must match one of the origins in the <code>Origin</code> header exactly, so it has to be set to something like <kbd>https://en.wikipedia.org</kbd> or <kbd>https://meta.wikimedia.org</kbd>. If this parameter does not match the <code>Origin</code> header, a 403 response will be returned. If this parameter matches the <code>Origin</code> header and the origin is whitelisted, the <code>Access-Control-Allow-Origin</code> and <code>Access-Control-Allow-Credentials</code> headers will be set.\n\nFor non-authenticated requests, specify the value <kbd>*</kbd>. This will cause the <code>Access-Control-Allow-Origin</code> header to be set, but <code>Access-Control-Allow-Credentials</code> will be <code>false</code> and all user-specific data will be restricted.",
        "apihelp-main-param-uselang": "Language to use for message translations. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> with <kbd>siprop=languages</kbd> returns a list of language codes, or specify <kbd>user</kbd> to use the current user's language preference, or specify <kbd>content</kbd> to use this wiki's content language.",
 
        "apihelp-block-description": "Block a user.",
index 8b612df..f733c47 100644 (file)
@@ -35,7 +35,7 @@
        "apihelp-main-param-requestid": "Cualquier valor dado aquí se incluirá en la respuesta. Se puede utilizar para distinguir solicitudes.",
        "apihelp-main-param-servedby": "Incluir el nombre del host que ha servido la solicitud en los resultados.",
        "apihelp-main-param-curtimestamp": "Incluir la marca de tiempo actual en el resultado.",
-       "apihelp-main-param-origin": "Cuando se accede a la API usando una petición AJAX de distinto dominio (CORS), establece este valor al dominio de origen. Debe ser incluido en cualquier petición pre-vuelo, y por lo tanto debe ser parte de la URI de la petición (no del cuerpo POST). Debe coincidir exactamente con uno de los orígenes de la cabecera <code>Origin</code>, por lo que debería ser algo como <kbd>https://en.wikipedia.org</kbd> o <kbd>https://meta.wikimedia.org</kbd>. Si este parámetro no coincide con la cabecera <code>Origin</code>, se devolverá una respuesta 403.\nSi este parámetro coincide con la cabecera <code>Origin</code> y el origen está en lista blanca, se creará una cabecera <code>Access-Control-Allow-Origin</code>.",
+       "apihelp-main-param-origin": "Cuando se accede a la API usando una petición AJAX de distinto dominio (CORS), se establece este valor al dominio de origen. Debe ser incluido en cualquier petición pre-vuelo, y por lo tanto debe ser parte de la URI de la petición (no del cuerpo POST). Debe coincidir exactamente con uno de los orígenes de la cabecera <code>Origin</code>, por lo que debería ser algo como <kbd>https://en.wikipedia.org</kbd> o <kbd>https://meta.wikimedia.org</kbd>. Si este parámetro no coincide con la cabecera <code>Origin</code>, se devolverá una respuesta 403.\nSi este parámetro coincide con la cabecera <code>Origin</code> y el origen está en lista blanca, se creará una cabecera <code>Access-Control-Allow-Origin</code>.",
        "apihelp-main-param-uselang": "El idioma que se usará para las traducciones de mensajes. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> con <kbd>siprop=languages</kbd> devuelve una lista de códigos de idiomas, o especifica <kbd>user</kbd> para usar la preferencia de idioma del usuario actual, o especifica <kbd>content</kbd> para usar el idioma de contenido de este wiki.",
        "apihelp-block-description": "Bloquear a un usuario.",
        "apihelp-block-param-user": "El nombre de usuario, dirección IP o intervalo de IP que quieres bloquear.",
@@ -82,6 +82,8 @@
        "apihelp-createaccount-param-language": "Código de idioma a establecer como predeterminado para el usuario (opcional, predeterminado al contenido del idioma).",
        "apihelp-createaccount-example-pass": "Crear usuario <kbd>testuser</kbd> con la contraseña <kbd>test123</kbd>.",
        "apihelp-createaccount-example-mail": "Crear usuario <kbd>testmailuser</kbd> y enviar una contraseña generada aleatoriamente.",
+       "apihelp-cspreport-description": "Utilizado por los navegadores para reportar violaciones de la política de seguridad de contenidos. Este módulo no debe usarse nunca, excepto cuando se usa automáticamente por un navegador web CSP compatible.",
+       "apihelp-cspreport-param-reportonly": "Marcar un informe de una política de vigilancia y no a una política forzada",
        "apihelp-cspreport-param-source": "Qué generó la cabecera CSP que provocó este informe",
        "apihelp-delete-description": "Borrar una página.",
        "apihelp-delete-param-title": "Título de la página a eliminar. No se puede utilizar junto a <var>$1pageid</var>.",
@@ -91,6 +93,7 @@
        "apihelp-delete-param-watch": "Añadir esta página a la lista de seguimiento del usuario actual.",
        "apihelp-delete-param-watchlist": "Incondicionalmente agregar o remover la página de la lista de seguimiento del usuario actual, usar las preferencias o no cambiar el seguimiento.",
        "apihelp-delete-param-unwatch": "Quitar la página de la lista de seguimiento del usuario actual.",
+       "apihelp-delete-param-oldimage": "El nombre de la imagen antigua es proporcionado conforme a lo dispuesto por [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
        "apihelp-delete-example-simple": "Borrar <kbd>Main Page</kbd>.",
        "apihelp-delete-example-reason": "Eliminar <kbd>Main Page</kbd> con el motivo <kbd>Preparing for move</kbd>.",
        "apihelp-disabled-description": "Se desactivó este módulo.",
        "apihelp-edit-param-nocreate": "Producir un error si la página no existe.",
        "apihelp-edit-param-watch": "Añadir la página a la lista de seguimiento del usuario actual.",
        "apihelp-edit-param-unwatch": "Quitar la página de la lista de seguimiento del usuario actual.",
+       "apihelp-edit-param-watchlist": "Incondicionalmente añadir o eliminar la página de lista del usuario actual, utilice referencias o no cambiar el reloj.",
+       "apihelp-edit-param-md5": "El hash MD5 del parámetro $1text, o los parámetros concatenados $1prependtext y $1appendtext. Si se establece, la edición no se hará a menos que el hash sea correcto.",
        "apihelp-edit-param-prependtext": "Añadir este texto al principio de la página. Reemplaza $1text.",
        "apihelp-edit-param-appendtext": "Añadir este texto al principio de la página. Reemplaza $1text.\n\nUtiliza $1section=new para añadir una nueva sección, en lugar de este parámetro.",
        "apihelp-edit-param-undo": "Deshacer esta revisión. Reemplaza $1text, $1prependtext y $1appendtext.",
        "apihelp-expandtemplates-param-title": "Título de la página.",
        "apihelp-expandtemplates-param-text": "Sintaxis wiki que se convertirá.",
        "apihelp-expandtemplates-param-revid": "Revisión de ID, para <nowiki>{{REVISIONID}}</nowiki> y variables similares.",
+       "apihelp-expandtemplates-param-prop": "Qué elementos de información se utilizan para llegar.\n\nTenga en cuenta que si no se seleccionan los valores, el resultado contendrá el wikitexto, pero la salida será en un formato obsoleto.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "El wikitexto expandido.",
        "apihelp-expandtemplates-paramvalue-prop-categories": "Cualesquiera categorías presentes en la entrada que no están representadas en salida de wikitexto.",
        "apihelp-expandtemplates-paramvalue-prop-properties": "Propiedades de página definidas por palabras mágicas en el wikitexto.",
+       "apihelp-expandtemplates-paramvalue-prop-volatile": "Si la salida es volátil y no debe ser reutilizada en otro lugar dentro de la página.",
        "apihelp-expandtemplates-paramvalue-prop-ttl": "El tiempo máximo tras el cual deberían invalidarse los resultados en caché.",
        "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "Da las variables de configuración JavaScript específicas para la página.",
        "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "Da las variables de configuración JavaScript específicas para la página como una cadena JSON.",
+       "apihelp-expandtemplates-paramvalue-prop-parsetree": "El árbol XML analiza el árbol de la entrada.",
        "apihelp-expandtemplates-param-includecomments": "Incluir o no los comentarios HTML en la salida.",
        "apihelp-expandtemplates-param-generatexml": "Generar un árbol de análisis XML (remplazado por $1prop=parsetree).",
        "apihelp-expandtemplates-example-simple": "Expandir el wikitexto <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por etiquetas.",
        "apihelp-feedrecentchanges-param-target": "Mostrar solo los cambios en las páginas enlazadas en esta.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar los cambios en páginas enlazadas con la página seleccionada.",
+       "apihelp-feedrecentchanges-param-categories": "Mostrar sólo cambios en las páginas en todas estas categorías.",
+       "apihelp-feedrecentchanges-param-categories_any": "Mostrar sólo cambios en las páginas en cualquiera de las categorías en lugar.",
        "apihelp-feedrecentchanges-example-simple": "Mostrar los cambios recientes.",
        "apihelp-feedrecentchanges-example-30days": "Mostrar los cambios recientes limitados a 30 días.",
        "apihelp-feedwatchlist-description": "Devuelve el canal de una lista de seguimiento.",
        "apihelp-help-param-submodules": "Incluir ayuda para submódulos del módulo con nombre.",
        "apihelp-help-param-recursivesubmodules": "Incluir ayuda para submódulos recursivamente.",
        "apihelp-help-param-helpformat": "Formato de salida de la ayuda.",
+       "apihelp-help-param-wrap": "Envolver el producto en una estructura de respuesta de la API estándar.",
        "apihelp-help-param-toc": "Incluir una tabla de contenidos en la salida HTML.",
        "apihelp-help-example-main": "Ayuda del módulo principal",
        "apihelp-help-example-submodules": "Ayuda para <kbd>action=query</kbd> y todos sus submódulos.",
        "apihelp-imagerotate-param-rotation": "Grados que rotar una imagen en sentido horario.",
        "apihelp-imagerotate-example-simple": "Rotar <kbd>File:Example.png</kbd> <kbd>90</kbd> grados.",
        "apihelp-imagerotate-example-generator": "Rotar todas las imágenes en <kbd>Category:Flip</kbd> <kbd>180</kbd> grados.",
+       "apihelp-import-description": "Importar una página desde otra wiki, o desde un archivo XML.\n\nTenga en cuenta que el HTTP POST debe hacerse como una carga de archivos (es decir, el uso de multipart/form-data) al enviar un archivo para el parámetro <var>xml</var>.",
        "apihelp-import-param-summary": "Resumen de importación de entrada del registro.",
        "apihelp-import-param-xml": "Se cargó el archivo XML.",
        "apihelp-import-param-interwikisource": "Para importaciones interwiki: wiki desde la que importar.",
        "apihelp-import-param-namespace": "Importar a este espacio de nombres. No puede usarse simultáneamente con <var>$1rootpage</var>.",
        "apihelp-import-param-rootpage": "Importar como subpágina de esta página. No puede usarse simultáneamente con <var>$1namespace</var>.",
        "apihelp-import-example-import": "Importar [[meta:Help:ParserFunctions]] al espacio de nombres 100 con todo el historial.",
-       "apihelp-login-description": "Iniciar sesión y obtener cookies de autenticación.\n\nSi inicias sesión sin problemas, las cookies necesarias se incluirán en los encabezados de respuesta HTTP. Si se produce algún error al iniciar sesión y este persiste, se puede regular para evitar los ataques masivos automatizados para adivinar contraseñas.",
+       "apihelp-linkaccount-description": "Vincular una cuenta de un proveedor de terceros para el usuario actual.",
+       "apihelp-linkaccount-example-link": "Iniciar el proceso de vincular a una cuenta de <kbd>Ejemplo</kbd>.",
+       "apihelp-login-description": "Iniciar sesión y obtener las cookies de autenticación.\n\nEsta acción solo se debe utilizar en combinación con [[Special:BotPasswords]]; para la cuenta de inicio de sesión no se utiliza y puede fallar sin previo aviso. Para iniciar la sesión de forma segura a la cuenta principal, utilice <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
+       "apihelp-login-description-nobotpasswords": "Iniciar sesión y obtener las cookies de autenticación.\n\nEsta acción esta obsoleta y puede fallar sin previo aviso. Para conectarse de forma segura, utilice <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
+       "apihelp-login-description-nonauthmanager": "Iniciar sesión y obtener cookies de autenticación.\n\nSi inicias sesión sin problemas, las cookies necesarias se incluirán en los encabezados de respuesta HTTP. Si se produce algún error al iniciar sesión y este persiste, se puede regular para evitar los ataques masivos automatizados de adivinar contraseñas.",
        "apihelp-login-param-name": "Nombre de usuario.",
        "apihelp-login-param-password": "Contraseña.",
        "apihelp-login-param-domain": "Dominio (opcional).",
        "apihelp-managetags-param-operation": "Qué operación realizar:\n;create: Crear una nueva etiqueta de cambio de uso manual.\n;delete: Eliminar una etiqueta de cambio de la base de datos, eliminando la etiqueta de todas las revisiones, cambios en entradas recientes y registros en los que se ha utilizado.\n;activate: Activar una etiqueta de cambio, permitiendo a los usuarios aplicarla manualmente.\n;deactivate: Desactivar una etiqueta de cambio, evitando que los usuarios la apliquen manualmente.",
        "apihelp-managetags-param-tag": "Etiqueta para crear, eliminar, activar o desactivar. Para crear una etiqueta, esta debe no existir. Para eliminarla, debe existir. Para activarla, debe existir y no estar en uso por ninguna extensión. Para desactivarla, debe estar activada y definida manualmente.",
        "apihelp-managetags-param-reason": "Un motivo opcional para crear, eliminar, activar o desactivar la etiqueta.",
+       "apihelp-managetags-param-ignorewarnings": "Ya sea para ignorar las advertencias que se emiten durante la operación.",
        "apihelp-managetags-example-create": "Crear una etiqueta llamada <kbd>spam</kbd> con el motivo <kbd>For use in edit patrolling</kbd>",
        "apihelp-managetags-example-delete": "Eliminar la etiqueta <kbd>vandlaism</kbd> con el motivo <kbd>Misspelt</kbd>",
        "apihelp-managetags-example-activate": "Activar una etiqueta llamada <kbd>spam</kbd> con el motivo <kbd>For use in edit patrolling</kbd>",
        "apihelp-managetags-example-deactivate": "Desactivar una etiqueta llamada <kbd>spam</kbd> con el motivo <kbd>No longer required</kbd>",
        "apihelp-mergehistory-description": "Fusionar historiales de páginas.",
+       "apihelp-mergehistory-param-from": "El título de la página desde la que se combinará la historia. No se puede utilizar junto con <var>$1fromid</var>.",
+       "apihelp-mergehistory-param-fromid": "Page ID de la página desde la que se combinara el historial. No se puede utilizar junto con <var>$1from</var>.",
+       "apihelp-mergehistory-param-to": "El título de la página desde la que se combinara el historial. No se puede utilizar junto con <var>$1toid</var>.",
+       "apihelp-mergehistory-param-toid": "Page ID de la página desde la que se combinara el historial. No se puede utilizar junto con <var>$1to</var>.",
+       "apihelp-mergehistory-param-timestamp": "La marca de tiempo de las revisiones se moverá del historial de la página de origen al historial de la página de destino. Si se omite, todo el historial de la página de la página de origen se fusionará en la página de destino.",
        "apihelp-mergehistory-param-reason": "Motivo para la fusión del historial.",
+       "apihelp-mergehistory-example-merge": "Combinar todo el historial de <kbd>Oldpage</kbd> en <kbd>Newpage</kbd>.",
+       "apihelp-mergehistory-example-merge-timestamp": "Combinar las revisiones de <kbd>Oldpage</kbd> hasta el <kbd>2015-12-31T04:37:41Z</kbd> en <kbd>Newpage</kbd>.",
        "apihelp-move-description": "Trasladar una página.",
        "apihelp-move-param-from": "Título de la página a renombrar. No se puede utilizar con <var>$1fromid</var>.",
        "apihelp-move-param-fromid": "ID de la página a renombrar. No se puede utilizar con <var>$1from</var>.",
        "apihelp-move-param-noredirect": "No crear una redirección.",
        "apihelp-move-param-watch": "Añadir la página y su redirección a la lista de seguimiento del usuario actual.",
        "apihelp-move-param-unwatch": "Eliminar la página y la redirección de la lista de seguimiento del usuario.",
+       "apihelp-move-param-watchlist": "Incondicionalmente puede añadir o eliminar la página de lista del usuario actual, utilizar referencias o no cambiar el reloj.",
        "apihelp-move-param-ignorewarnings": "Ignorar cualquier aviso.",
        "apihelp-move-example-move": "Trasladar <kbd>Badtitle</kbd> a <kbd>Goodtitle</kbd> sin dejar una redirección.",
        "apihelp-opensearch-description": "Buscar en el wiki mediante el protocolo OpenSearch.",
        "apihelp-paraminfo-param-modules": "Lista de los nombres de los módulos (valores de los parámetros <var>action</var> y <var>format</var> o <kbd>main</kbd>). Se pueden especificar los submódulos con un <kbd>+</kbd>.",
        "apihelp-paraminfo-param-helpformat": "Formato de las cadenas de ayuda.",
        "apihelp-paraminfo-param-querymodules": "Lista de los nombres de los módulos de consulta (valor de los parámetros <var>prop</var>, <var>meta</var> or <var>list</var>). Utiliza <kbd>$1modules=query+foo</kbd> en vez de <kbd>$1querymodules=foo</kbd>.",
+       "apihelp-paraminfo-param-mainmodule": "Obtener también información sobre el módulo principal (primer nivel). Utilizar <kbd>$1modules=main</kbd> en su lugar.",
+       "apihelp-paraminfo-param-pagesetmodule": "Obtener también información sobre el módulo PageSet (Proporcionar títulos= y amigos).",
        "apihelp-paraminfo-param-formatmodules": "Lista de los nombres del formato de los módulos (valor del parámetro <var>format</var>). Utiliza <var>$1modules</var> en su lugar.",
        "apihelp-paraminfo-example-1": "Mostrar información para <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> y <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
        "apihelp-parse-param-title": "Título de la página a la que pertenece el texto. Si se omite se debe especificar <var>$1contentmodel</var> y se debe utilizar el [[API]] como título.",
        "apihelp-parse-paramvalue-prop-properties": "Da varias propiedades definidas en el wikitexto analizado.",
        "apihelp-parse-paramvalue-prop-limitreportdata": "Da el informe del límite de forma estructurada. No da datos si <var>$1disablelimitreport</var> está establecido.",
        "apihelp-parse-paramvalue-prop-limitreporthtml": "Da la versión HTML del informe del límite. No da datos si <var>$1disablelimitreport</var> está establecido.",
+       "apihelp-parse-paramvalue-prop-parsetree": "El árbol de análisis sintáctico XML del contenido de la revisión (requiere modelo de contenido <code>$1</code>)",
+       "apihelp-parse-param-pst": "Guardar previamente los cambios antes de transformar la entrada antes de analizarla. Sólo es válido cuando se utiliza con el texto.",
+       "apihelp-parse-param-onlypst": "Guardar previamente los cambios antes de transformar (PST) en la entrada. Devuelve el mismo wikitexto, después de que un PST se ha aplicado. Sólo es válido cuando se utiliza con <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "Incluye enlaces de idiomas proporcionados por las extensiones (para utilizar con <kbd>$1prop=langlinks</kbd>).",
+       "apihelp-parse-param-disablelimitreport": "Omitir el informe de límite (\"NewPP limit report\") desde la salida del analizador.",
        "apihelp-parse-param-disablepp": "Usa <var>$1disablelimitreport</var> en su lugar.",
        "apihelp-parse-param-disableeditsection": "Omitir los enlaces de edición de sección de la salida del analizador.",
+       "apihelp-parse-param-disabletidy": "No ejecute la limpieza HTML (por ejemplo ordenada) en la salida del analizador.",
+       "apihelp-parse-param-generatexml": "Generar árbol de análisis sintáctico XML (requiere modelo de contenido <code>$1</code>; sustituido por <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "Analizar en modo de vista previa.",
        "apihelp-parse-param-sectionpreview": "Analizar sección en modo de vista previa (también activa el modo de vista previa).",
        "apihelp-parse-param-disabletoc": "Omitir la tabla de contenidos en la salida.",
+       "apihelp-parse-param-contentformat": "Formato de serialización de contenido utilizado para la introducción de texto. Sólo es válido cuando se utiliza con $1text.",
        "apihelp-parse-example-page": "Analizar una página.",
        "apihelp-parse-example-text": "Analizar wikitexto.",
        "apihelp-parse-example-texttitle": "Analizar wikitexto, especificando el título de la página.",
        "apihelp-protect-param-pageid": "ID de la página a (des)proteger. No se puede utilizar con $1title.",
        "apihelp-protect-param-protections": "Lista de los niveles de protección, con formato <kbd>action=level</kbd> (por ejemplo: <kbd>edit=sysop</kbd>).\n\n<strong>Nota:</strong> Cualquier acción no mencionada tendrá las restricciones eliminadas.",
        "apihelp-protect-param-reason": "Motivo de la (des)protección.",
+       "apihelp-protect-param-tags": "Cambiar las etiquetas para aplicar a la entrada en el registro de protección.",
        "apihelp-protect-param-cascade": "Activar la protección en cascada (o sea, proteger plantillas e imágenes transcluidas usadas en esta página). Se ignorará si ninguno de los niveles de protección dados son compatibles con la función de cascada.",
        "apihelp-protect-example-protect": "Proteger una página",
        "apihelp-protect-example-unprotect": "Desproteger una página estableciendo la restricción a <kbd>all</kbd>.",
        "apihelp-query+allfileusages-example-generator": "Recupera las páginas que contienen los archivos.",
        "apihelp-query+allimages-description": "Enumerar todas las imágenes secuencialmente.",
        "apihelp-query+allimages-param-sort": "Propiedad por la que realizar la ordenación.",
+       "apihelp-query+allimages-param-dir": "La dirección en la que se listará.",
        "apihelp-query+allimages-param-from": "El título de la imagen para comenzar la enumeración. Solo puede utilizarse con $1sort=name.",
        "apihelp-query+allimages-param-to": "El título de la imagen para detener la enumeración. Solo puede utilizarse con $1sort=name.",
        "apihelp-query+allimages-param-start": "El sello de tiempo para comenzar la enumeración. Solo puede utilizarse con $1sort=timestamp.",
        "apihelp-query+alllinks-paramvalue-prop-title": "Añade el título del enlace.",
        "apihelp-query+alllinks-param-namespace": "El espacio de nombres que enumerar.",
        "apihelp-query+alllinks-param-limit": "Cuántos elementos en total se devolverán.",
+       "apihelp-query+alllinks-param-dir": "La dirección en la que se listará.",
+       "apihelp-query+alllinks-example-unique": "Lista de títulos vinculados únicamente.",
        "apihelp-query+alllinks-example-unique-generator": "Obtiene todos los títulos enlazados, marcando los que falten.",
+       "apihelp-query+alllinks-example-generator": "Obtiene páginas que contienen los enlaces.",
+       "apihelp-query+allmessages-description": "Devolver los mensajes de este sitio.",
        "apihelp-query+allmessages-param-prop": "Qué propiedades se obtendrán.",
+       "apihelp-query+allmessages-param-nocontent": "Si se establece, no incluya el contenido de los mensajes en la salida.",
+       "apihelp-query+allmessages-param-args": "Los argumentos que se sustituyen en el mensaje.",
        "apihelp-query+allmessages-param-filter": "Devolver solo mensajes con nombres que contengan esta cadena.",
        "apihelp-query+allmessages-param-customised": "Devolver solo mensajes en este estado de personalización.",
        "apihelp-query+allmessages-param-lang": "Devolver mensajes en este idioma.",
        "apihelp-query+allpages-param-maxsize": "Limitar a páginas con este número máximo de bytes.",
        "apihelp-query+allpages-param-prtype": "Limitar a páginas protegidas.",
        "apihelp-query+allpages-param-limit": "Cuántas páginas en total se devolverán.",
+       "apihelp-query+allpages-param-dir": "La dirección en la que se listará.",
+       "apihelp-query+allpages-param-filterlanglinks": "Filtrar en función de si una página tiene langlinks. Tenga en cuenta que esto no puede considerar langlinks agregados por extensiones.",
        "apihelp-query+allpages-example-B": "Mostrar una lista de páginas que empiecen con la letra <kbd>B</kbd>.",
        "apihelp-query+allpages-example-generator": "Mostrar información acerca de 4 páginas que empiecen por la letra <kbd>T</kbd>.",
        "apihelp-query+allpages-example-generator-revisions": "Mostrar el contenido de las 2 primeras páginas que no redirijan y empiecen por <kbd>Re</kbd>.",
        "apihelp-query+allredirects-description": "Obtener la lista de todas las redirecciones a un espacio de nombres.",
+       "apihelp-query+allredirects-param-from": "El título de la redirección para iniciar la enumeración.",
+       "apihelp-query+allredirects-param-to": "El título de la redirección para detener la enumeración.",
        "apihelp-query+allredirects-param-prefix": "Buscar todas las páginas de destino que empiecen con este valor.",
        "apihelp-query+allredirects-param-prop": "Qué piezas de información incluir:",
        "apihelp-query+allredirects-paramvalue-prop-title": "Añade el título de la redirección.",
+       "apihelp-query+allredirects-param-namespace": "El espacio de nombres a enumerar.",
        "apihelp-query+allredirects-param-limit": "Cuántos elementos se devolverán.",
+       "apihelp-query+allredirects-param-dir": "La dirección en la que se listará.",
+       "apihelp-query+allredirects-example-unique": "La lista de páginas de destino.",
+       "apihelp-query+allredirects-example-unique-generator": "Obtiene todas las páginas de destino, marcando los que faltan.",
+       "apihelp-query+allredirects-example-generator": "Obtiene páginas que contienen las redirecciones.",
        "apihelp-query+allrevisions-description": "Listar todas las revisiones.",
+       "apihelp-query+allrevisions-param-start": "La marca de tiempo para iniciar la enumeración.",
+       "apihelp-query+allrevisions-param-end": "La marca de tiempo para detener la enumeración.",
        "apihelp-query+allrevisions-param-user": "Listar solo las revisiones de este usuario.",
        "apihelp-query+allrevisions-param-excludeuser": "No listar las revisiones de este usuario.",
        "apihelp-query+allrevisions-param-namespace": "Listar solo las páginas en este espacio de nombres.",
        "apihelp-query+allrevisions-example-user": "Listar las últimas 50 contribuciones del usuario <kbd>Example</kbd>.",
        "apihelp-query+allrevisions-example-ns-main": "Listar las primeras 50 revisiones en el espacio de nombres principal.",
+       "apihelp-query+mystashedfiles-description": "Obtener una lista de archivos en la corriente de carga de usuarios.",
+       "apihelp-query+mystashedfiles-param-prop": "Propiedades a buscar para los archivos.",
+       "apihelp-query+mystashedfiles-paramvalue-prop-size": "Buscar el tamaño del archivo y las dimensiones de la imagen.",
        "apihelp-query+mystashedfiles-param-limit": "Cuántos archivos obtener.",
        "apihelp-query+alltransclusions-param-from": "El título de la transclusión por la que empezar la enumeración.",
        "apihelp-query+alltransclusions-param-to": "El título de la transclusión por la que terminar la enumeración.",
index 079eeb2..5f09064 100644 (file)
@@ -29,6 +29,8 @@
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "Wikitestu zabaldua.",
        "apihelp-feedcontributions-param-year": "Urtetik aurrera (eta lehenagotik)",
        "apihelp-feedcontributions-param-month": "Hilabetetik aurrera (eta lehenagotik)",
+       "apihelp-feedcontributions-param-newonly": "Orrialde sorkuntza direnak soilik erakutsi",
+       "apihelp-feedcontributions-param-hideminor": "Aldaketa txikiak ezkutatu",
        "apihelp-feedrecentchanges-param-hideminor": "Ezkutatu aldaketa txikiak.",
        "apihelp-feedrecentchanges-param-hidebots": "Ezkutatu botek egindako aldaketak.",
        "apihelp-feedrecentchanges-param-hideanons": "Ezkutatu erabiltzaile anonimoek egindako aldaketak.",
index 4780ecd..2ae81d4 100644 (file)
        "apihelp-query+allpages-param-minsize": "محدودکردن به صفحه‌هایی که همراه دست کم این تعداد بایت است.",
        "apihelp-query+allpages-param-limit": "میزان کل صفحه‌ها برای بازگرداندن.",
        "apihelp-query+allredirects-param-limit": "تعداد آیتم‌ها برای بازگرداندن.",
+       "apihelp-query+allrevisions-description": "فهرست همه نسخه‌ها",
+       "apihelp-query+mystashedfiles-param-limit": "تعداد پرونده‌هایی که باید بگیرد.",
+       "apihelp-query+allusers-param-dir": "جهتی که باید مرتب شود.",
+       "apihelp-query+allusers-paramvalue-prop-rights": "فهرست دسترسی‌هایی که کاربر دارد.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "شمار ويرایش کاربر را می‌افزايد",
        "apihelp-query+allusers-paramvalue-prop-registration": "زمان ثبت نام کاربر را در صورت وجود می‌افزايد (ممکن است خالی باشد)",
        "apihelp-query+allusers-param-limit": "تعداد کل نام‌های کاربری برای بازگرداندن.",
        "apihelp-query+categories-param-limit": "چه میزان رده بازگردانده شود.",
        "apihelp-query+categories-param-categories": "فقط این رده‌ها فهرست شود. کاربردی برای بررسی وجود یک صفحهٔ مشخص در یک ردهٔ مشخص.",
        "apihelp-query+categorymembers-description": "فهرست‌کردن همهٔ صفحه‌ها در یک ردهٔ مشخص‌شده.",
+       "apihelp-query+categorymembers-paramvalue-prop-ids": "افزودن شناسه صفحه",
        "apihelp-query+categorymembers-param-sort": "خصوصیت برای مرتب‌سازی",
        "apihelp-query+categorymembers-param-dir": "جهت مرتب شدن",
        "apihelp-query+categorymembers-param-startsortkey": "جایش از $1starthexsortkey استفاده کنید.",
+       "apihelp-query+deletedrevs-param-from": "شروع فهرست کردن مواردی که این عنوان را دارند.",
+       "apihelp-query+deletedrevs-param-to": "خاتمه فهرست کردن مواردی که این عنوان را دارند.",
        "apihelp-query+deletedrevs-param-namespace": "فقط صفحات ین فضای نام را فهرست کن.",
        "apihelp-query+deletedrevs-param-limit": "حداکثر تعداد بازنگری‌هايي که فهرست شوند.",
+       "apihelp-query+fileusage-paramvalue-prop-title": "عنوان هر صفحه.",
+       "apihelp-query+fileusage-param-limit": "تعدادی که باید بازگردانده شود.",
+       "apihelp-query+imageinfo-paramvalue-prop-dimensions": "نام مستعار برای size",
+       "apihelp-query+imageinfo-paramvalue-prop-sha1": "افزودن  SHA-1 hash برای پرونده",
+       "apihelp-query+imageinfo-paramvalue-prop-mime": "افزودن نوع MIME برای پرونده",
        "apihelp-query+imageinfo-param-end": "زمان توقف فهرست کردن.",
        "apihelp-query+imageinfo-param-urlheight": "مشابه $1urlwidth.",
+       "apihelp-query+images-param-limit": "تعداد پرونده‌هایی که باید بازگرداند.",
        "apihelp-query+info-description": "دریافت اطلاعات سادهٔ صفحه.",
        "apihelp-query+iwbacklinks-param-prefix": "پیشوند میان‌ویکی.",
        "apihelp-query+iwbacklinks-param-title": "پیوند میان‌ویکی برای جستجو. باید همراه <var>$1blprefix</var> استفاده شود.",
        "apihelp-query+iwbacklinks-param-limit": "تعداد صفحه‌ها برای بازگرداندن.",
+       "apihelp-query+iwbacklinks-param-prop": "خصوصیتی که باید گرفته شود.",
+       "apihelp-query+iwlinks-paramvalue-prop-url": "افزودن نشانی اینترنتی کامل.",
+       "apihelp-query+langbacklinks-param-prop": "خصوصیتی که باید گرفته شود:",
+       "apihelp-query+langlinks-paramvalue-prop-url": "افزودن نشانی اینترنتی کامل.",
+       "apihelp-query+links-param-limit": "تعداد پیوندهایی که باید بازگرداند.",
+       "apihelp-query+linkshere-param-prop": "خصوصیتی که باید گرفته شود:",
+       "apihelp-query+linkshere-paramvalue-prop-pageid": "شناسه صفحه هر صفحه.",
+       "apihelp-query+linkshere-paramvalue-prop-title": "عنوان هر صفحه.",
+       "apihelp-query+linkshere-paramvalue-prop-redirect": "اگر صفحه تغییر مسیر بود برچسب بزن.",
+       "apihelp-query+linkshere-param-namespace": "فقط صفحات این فضای نام را فهرست کن.",
        "apihelp-query+linkshere-param-limit": "تعداد برای بازگرداندن.",
        "apihelp-query+logevents-description": "دریافت رویدادها از سیاهه‌ها.",
+       "apihelp-query+logevents-param-prop": "خصوصیتی که باید گرفته شود.",
+       "apihelp-query+logevents-paramvalue-prop-ids": "افزودن شناسه سیاهه رویداد.",
+       "apihelp-query+pageswithprop-paramvalue-prop-ids": "افزودن شناسه صفحه",
+       "apihelp-query+pageswithprop-param-dir": "جهت مرتب شدن",
        "apihelp-query+prefixsearch-param-search": "جستجوی رشته",
        "apihelp-query+prefixsearch-param-namespace": "فضاهای نامی برای جستجو",
        "apihelp-query+prefixsearch-param-limit": "حداکثر تعداد نتایج برای بازگرداندن.",
        "apihelp-query+random-example-generator": "بازگرداندن اطلاعات صفحه دربارهٔ دو صفحهٔ تصادفی از فضای نام اصلی",
        "apihelp-query+recentchanges-param-start": "برچسب زمانی برای آغاز شمارش از.",
        "apihelp-query+recentchanges-param-end": "برچسب زمانی برای پایان شمارش.",
+       "apihelp-query+recentchanges-paramvalue-prop-flags": "افزودن برچسب برای ویرایش.",
+       "apihelp-query+recentchanges-paramvalue-prop-timestamp": "افزودن زمان ویرایش.",
+       "apihelp-query+redirects-paramvalue-prop-title": "عنوان هر تغییرمسیر.",
        "apihelp-query+redirects-param-limit": "تعداد تغییرمسیرها برای بازگرداندن.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "متن نسخه ویرایش.",
+       "apihelp-query+revisions+base-paramvalue-prop-tags": "برچسب برای نسخه‌های ویرایش.",
+       "apihelp-query+siteinfo-param-prop": "اطلاعاتی که باید گرفته‌شود:",
+       "apihelp-query+siteinfo-paramvalue-prop-statistics": "بازرگرداندن آمار سایت.",
+       "apihelp-query+siteinfo-example-simple": "دریافت اطلاعات سایت.",
+       "apihelp-query+tags-description": "فهرست تغییرات برچسب‌ها.",
+       "apihelp-query+tags-param-limit": "حداکثر تعداد برچسب‌ها برای فهرست شدن.",
+       "apihelp-query+tags-param-prop": "خصوصیتی که باید گرفته شود:",
+       "apihelp-query+tags-paramvalue-prop-name": "افزودن نام برچسب.",
+       "apihelp-query+transcludedin-paramvalue-prop-title": "عنوان هر صفحه.",
+       "apihelp-query+watchlist-paramvalue-type-log": "مدخل‌های سیاهه.",
+       "apihelp-stashedit-param-text": "محتوای صفحه.",
+       "apihelp-stashedit-param-contentmodel": "مدل محتوایی محتوای جدید",
+       "apihelp-stashedit-param-summary": "خلاصه تغییرات.",
+       "apihelp-tag-param-reason": "دلیل تغییر.",
+       "apihelp-unblock-description": "بازکردن کاربر.",
+       "apihelp-undelete-param-reason": "دلیل احیا.",
+       "apihelp-upload-param-filename": "نام پرونده مقصد.",
        "apihelp-upload-param-ignorewarnings": "چشم‌پوشی از همهٔ هشدارها.",
+       "apihelp-upload-param-file": "محتوی پرونده.",
+       "apihelp-upload-param-url": "نشانی اینترنتی برای دریافت فایل.",
        "apihelp-userrights-param-user": "نام کاربری.",
+       "apihelp-userrights-param-userid": "شناسه کاربر.",
+       "apihelp-userrights-param-reason": "دلیل تغییر.",
+       "apihelp-none-description": "بیرون‌ریزی هیچ.",
+       "api-format-title": "نتیجه ای‌پی‌آی مدیاویکی",
+       "api-help-main-header": "پودمان اصلی",
+       "api-help-source": "منبع: $1",
        "api-help-param-deprecated": "توصیه.",
        "api-help-param-limit": "بيش از $1 مجاز نيست",
        "api-help-param-limit2": "بيش از $1 (برای ربات‌ها $2) مجاز نيست",
+       "api-help-param-default": "پیش‌فرض: $1",
        "api-credits-header": "اعتبار"
 }
index a10c486..46bb3e6 100644 (file)
@@ -38,7 +38,7 @@
        "apihelp-main-param-requestid": "Toute valeur fournie ici sera incluse dans la réponse. Peut être utilisé pour distinguer des demandes.",
        "apihelp-main-param-servedby": "Inclure le nom d’hôte qui a renvoyé la requête dans les résultats.",
        "apihelp-main-param-curtimestamp": "Inclure l’horodatage actuel dans le résultat.",
-       "apihelp-main-param-origin": "En accédant à l’API en utilisant une requête AJAX inter-domaines (CORS), mettre le domaine d’origine dans ce paramètre. Il doit être inclus dans toute requête de pre-flight, et doit donc faire partie de l’URI de la requête (pas du corps du POST). Il doit correspondre exactement à une des origines dans l’entête <code>Origin</code> header, donc il doit être fixé avec quelque chose comme <kbd>https://en.wikipedia.org</kbd> ou <kbd>https://meta.wikimedia.org</kbd>. Si ce paramètre ne correspond pas à l’entête <code>Origin</code>, une réponse 403 sera renvoyée. Si ce paramètre correspond à l’entête <code>Origin</code> et que l’origine est en liste blanche, un entête <code>Access-Control-Allow-Origin</code> sera positionné.",
+       "apihelp-main-param-origin": "En accédant à l’API en utilisant une requête AJAX inter-domaines (CORS), mettre le domaine d’origine dans ce paramètre. Il doit être inclus dans toute requête de pre-flight, et doit donc faire partie de l’URI de la requête (pas du corps du POST).\n\nPour les requêtes authentifiées, il doit correspondre exactement à une des origines dans l’entête <code>Origin</code> header, donc il doit être fixé avec quelque chose comme <kbd>https://en.wikipedia.org</kbd> ou <kbd>https://meta.wikimedia.org</kbd>. Si ce paramètre ne correspond pas à l’entête <code>Origin</code>, une réponse 403 sera renvoyée. Si ce paramètre correspond à l’entête <code>Origin</code> et que l’origine est en liste blanche, des entêtes <code>Access-Control-Allow-Origin</code> et <code>Access-Control-Allow-Credentials</code> seront positionnés.\n\nPour les requêtes non authentifiées, spécifiez la valeur <kbd>*</kbd>. Cela positionnera l’entête <code>Access-Control-Allow-Origin</code>, mais <code>Access-Control-Allow-Credentials</code> vaudra <code>false</code> et toutes les données spécifiques à l’utilisateur seront filtrées.",
        "apihelp-main-param-uselang": "Langue à utiliser pour les traductions de message. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> avec <kbd>siprop=languages</kbd> renvoie une liste de codes de langue, ou en spécifiant <kbd>user</kbd> pour utiliser la préférence de langue de l’utilisateur actuel, ou en spécifiant <kbd>content</kbd> pour utiliser le langage du contenu de ce wiki.",
        "apihelp-block-description": "Bloquer un utilisateur.",
        "apihelp-block-param-user": "Nom d’utilisateur, adresse IP ou plage d’adresses IP que vous voulez bloquer.",
index 2a39745..7d8da1e 100644 (file)
@@ -24,7 +24,7 @@
        "apihelp-main-param-requestid": "כל ערך שיינתן כאן ייכלל בתשובה. אפשר להשתמש בזה כדי להבדיל בין בקשות.",
        "apihelp-main-param-servedby": "לכלול את שם המארח ששירת את הבקשה בתוצאות.",
        "apihelp-main-param-curtimestamp": "הכללת חותם־הזמן הנוכחי בתוצאה.",
-       "apihelp-main-param-origin": "בעת גישה ל־API עם בקשת AJAX חוצה מתחמים (CORS), יש להציב כאן את המתחם שהבקשה יוצאת ממנו. זה היה להיות כלול בכל בקשה מקדימה, ולכן הוא חייב להיות חלק מה־URI של הבקשה (לא גוף ה־POST). זה חייב להיות תואם במדויק לאחד המקורות בכותרת <code>Origin</code>, כך שזה צריך להיות מוגדר למשהו כמו <kbd>https://en.wikipedia.org</kbd> או <kbd>https://meta.wikimedia.org</kbd>. אם הפרמטר הזה אינו תואם לכותרת <code>Origin</code>, תוחזר תשובת 403. אם הפרמטר הזה תורם לכותרת <code>Origin</code> והמקור נמצא ברשימה הלבנה, תוגדר כותרת <code>Access-Control-Allow-Origin</code>.",
+       "apihelp-main-param-origin": "בעת גישה ל־API עם בקשת AJAX חוצה מתחמים (CORS), יש להציב כאן את המתחם שהבקשה יוצאת ממנו. זה היה להיות כלול בכל בקשה מקדימה, ולכן הוא חייב להיות חלק מה־URI של הבקשה (לא גוף ה־POST).\n\nעבור בקשות מאומתות, זה חייב להיות תואם במדויק לאחד המקורות בכותרת <code>Origin</code>, כך שזה צריך להיות מוגדר למשהו כמו <kbd>https://en.wikipedia.org</kbd> או <kbd>https://meta.wikimedia.org</kbd>. אם הפרמטר הזה אינו תואם לכותרת <code>Origin</code>, תוחזר תשובת 403. אם הפרמטר הזה תורם לכותרת <code>Origin</code> והמקור נמצא ברשימה הלבנה, תוגדרנה הכותרות <code>Access-Control-Allow-Origin</code> ו־<code>Access-Control-Allow-Credentials</code>.\n\nעבור בקשות בלתי־מאומתות, יש לציין את הערך <kbd>*</kbd>. זה יגרום לכותרת להיות <code>Access-Control-Allow-Origin</code>, אבל <code>Access-Control-Allow-Credentials</code> תהיה <code>false</code> וכל הנתונים הייחודיים למשתמש יהיו מוגבלים.",
        "apihelp-main-param-uselang": "באיזו שפה להשתמש לתרגומי הודעות. הקריאה <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> עם <kbd>siprop=languages</kbd> מחזירה רשימת קודים. ציון <kbd>user</kbd> כדי להשתמש בהעדפת השפה של המשתמש הנוכחי, וציון <kbd>content</kbd> להשתמש בקוד השפה של הוויקי הזה.",
        "apihelp-block-description": "חסימת משתמש.",
        "apihelp-block-param-user": "שם משתמש, כתובת IP, או טווח IP שהנך רוצה לחסום.",
@@ -95,7 +95,7 @@
        "apihelp-edit-param-section": "מספר הפסקה <kbd>0</kbd> לפסקה העליונה, <kbd>new</kbd> לפסקה חדשה.",
        "apihelp-edit-param-sectiontitle": "הכותרת לפסקה החדשה.",
        "apihelp-edit-param-text": "תוכן הדף.",
-       "apihelp-edit-param-summary": "תקצ×\99ר ×¢×¨×\99×\9b×\94. ×\92×\9d ×\92ותרת פסקה כש־$1section=new ו־$1sectiontitle אינו מוגדר.",
+       "apihelp-edit-param-summary": "תקצ×\99ר ×¢×¨×\99×\9b×\94. ×\92×\9d ×\9bותרת פסקה כש־$1section=new ו־$1sectiontitle אינו מוגדר.",
        "apihelp-edit-param-tags": "אילו תגי שינוי להחיל על הגרסה.",
        "apihelp-edit-param-minor": "עריכה משנית.",
        "apihelp-edit-param-notminor": "שינוי לא משני.",
index 6a2f836..57e124c 100644 (file)
        "api-help-examples": "{{PLURAL:$1|Esempio|Esempi}}:",
        "api-help-permissions": "{{PLURAL:$1|Permesso|Permessi}}:",
        "api-help-open-in-apisandbox": "<small>[apri in una sandbox]</small>",
-       "api-help-authmanager-general-usage": "La procedura generale per usare questo modulo Ã©:\n# Ottenere i campi disponibili da <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> con <kbd>amirequestsfor=$4</kbd>, e un token <kbd>$5</kbd> da <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.\n# Mostra i campi all'utente e ottieni i dati che invia.\n# Esegui un post a questo modulo, fornendo <var>$1returnurl</var> e ogni campo rilevante.\n# Controlla <samp>status</samp> nella response.\n#* Se hai ricevuto <samp>PASS</samp> o <samp>FAIL</samp>, hai finito. L'operazione nel primo caso è andata a buon fine, nel secondo no.\n#* Se hai ricevuto <samp>UI</samp>, mostra i nuovi campi all'utente e ottieni i dati che invia. Esegui un post a questo modulo con <var>$1continue</var> e i campi rilevanti settati, quindi ripeti il punto 4.\n#* Se hai ricevuto <samp>REDIRECT</samp>, dirigi l'utente a <samp>redirecttarget</samp> e aspetta che ritorni a <var>$1returnurl</var>. A quel punto esegui un post a questo modulo con <var>$1continue</var> e ogni campo passato all'URL di ritorno, e ripeti il punto 4.\n#* Se hai ricevuto <samp>RESTART</samp>, vuol dire che l'autenticazione ha funzionato ma non abbiamo un account collegato. Potresti considerare questo caso come <samp>UI</samp> o come <samp>FAIL</samp>.",
+       "api-help-authmanager-general-usage": "La procedura generale per usare questo modulo Ã¨:\n# Ottenere i campi disponibili da <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> con <kbd>amirequestsfor=$4</kbd>, e un token <kbd>$5</kbd> da <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.\n# Mostra i campi all'utente e ottieni i dati che invia.\n# Esegui un post a questo modulo, fornendo <var>$1returnurl</var> e ogni campo rilevante.\n# Controlla <samp>status</samp> nella response.\n#* Se hai ricevuto <samp>PASS</samp> o <samp>FAIL</samp>, hai finito. L'operazione nel primo caso è andata a buon fine, nel secondo no.\n#* Se hai ricevuto <samp>UI</samp>, mostra i nuovi campi all'utente e ottieni i dati che invia. Esegui un post a questo modulo con <var>$1continue</var> e i campi rilevanti settati, quindi ripeti il punto 4.\n#* Se hai ricevuto <samp>REDIRECT</samp>, dirigi l'utente a <samp>redirecttarget</samp> e aspetta che ritorni a <var>$1returnurl</var>. A quel punto esegui un post a questo modulo con <var>$1continue</var> e ogni campo passato all'URL di ritorno, e ripeti il punto 4.\n#* Se hai ricevuto <samp>RESTART</samp>, vuol dire che l'autenticazione ha funzionato ma non abbiamo un account collegato. Potresti considerare questo caso come <samp>UI</samp> o come <samp>FAIL</samp>.",
        "api-help-authmanagerhelper-messageformat": "Formato da utilizzare per per la restituzione dei messaggi.",
        "api-help-authmanagerhelper-preservestate": "Conserva lo stato da un precedente tentativo di accesso non riuscito, se possibile.",
        "api-help-authmanagerhelper-returnurl": "URL di ritorno per i flussi di autenticazione di terze parti, deve essere assoluto. E' necessario fornirlo, oppure va fornito <var>$1continue</var>.\n\nAlla ricezione di una risposta <samp>REDIRECT</samp>, in genere si apre un browser o una vista web all'URL specificato <samp>redirecttarget</samp> per un flusso di autenticazione di terze parti. Quando questo è completato, la terza parte invierà il browser o la vista web a questo URL. Dovresti estrarre qualsiasi parametro POST o della richiesta dall'URL e passarli come un request <var>$1continue</var> a questo modulo API.",
index e0eef1c..2712c13 100644 (file)
        "apihelp-feedcontributions-param-deletedonly": "削除された投稿記録のみ表示します。",
        "apihelp-feedcontributions-param-toponly": "最新版の編集のみ表示します。",
        "apihelp-feedcontributions-param-newonly": "ページ作成を伴う編集のみを表示します。",
+       "apihelp-feedcontributions-param-hideminor": "細部の編集を非表示",
        "apihelp-feedcontributions-param-showsizediff": "版間のサイズの増減を表示する。",
        "apihelp-feedcontributions-example-simple": "利用者 <kbd>Example</kbd> の投稿記録を取得する。",
        "apihelp-feedrecentchanges-description": "最近の更新フィードを返します。",
index 371347b..1ec5b50 100644 (file)
@@ -41,7 +41,7 @@
        "apihelp-block-example-ip-simple": "IP <kbd>192.0.2.5</kbd>에 대해 <kbd>First strike</kbd>라는 이유로 3일 간 차단하기",
        "apihelp-block-example-user-complex": "사용자 <kbd>Vandal</kbd>을 <kbd>Vandalism</kbd>이라는 이유로 무기한 차단하며 계정 생성 및 이메일 발송을 막기",
        "apihelp-changeauthenticationdata-description": "현재 사용자의 인증 데이터를 변경합니다.",
-       "apihelp-changeauthenticationdata-example-password": "í\98\84ì\9e¬ ì\82¬ì\9a©ì\9e\90ì\9d\98 ë¹\84ë°\80ë²\88í\98¸ë¥¼ <kbd>ExamplePassword</kbd>ë¡\9c ë³\80ê²½í\95\98는 것을 시도합니다.",
+       "apihelp-changeauthenticationdata-example-password": "í\98\84ì\9e¬ ì\82¬ì\9a©ì\9e\90ì\9d\98 ë¹\84ë°\80ë²\88í\98¸ë¥¼ <kbd>ExamplePassword</kbd>ë¡\9c ë°\94꾸는 것을 시도합니다.",
        "apihelp-checktoken-description": "<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>의 토큰의 유효성을 확인합니다.",
        "apihelp-checktoken-param-type": "테스트되는 토큰의 종류.",
        "apihelp-checktoken-param-token": "테스트할 토큰",
        "apihelp-emailuser-param-subject": "제목 헤더.",
        "apihelp-emailuser-param-text": "메일 본문.",
        "apihelp-emailuser-param-ccme": "자신에게 메일의 복사본을 보냅니다.",
-       "apihelp-emailuser-example-email": "<kbd>WikiSysop</kbd> 사용자에게 텍스트 <kbd>콘텐츠</kbd>로 이메일을 보냅니다.",
+       "apihelp-emailuser-example-email": "<kbd>WikiSysop</kbd> 사용자에게 텍스트 <kbd>Content</kbd>로 이메일을 보냅니다.",
        "apihelp-expandtemplates-description": "모든 틀을 위키텍스트로 확장.",
        "apihelp-expandtemplates-param-title": "문서 제목",
        "apihelp-expandtemplates-param-text": "변환할 위키텍스트.",
        "apihelp-paraminfo-description": "API 모듈의 정보를 가져옵니다.",
        "apihelp-paraminfo-param-helpformat": "도움말 문자열 포맷.",
        "apihelp-parse-param-summary": "구문 분석할 요약입니다.",
+       "apihelp-parse-paramvalue-prop-text": "위키텍스트의 구문 분석된 텍스트를 제공합니다.",
+       "apihelp-parse-paramvalue-prop-langlinks": "구문 분석된 위키텍스트의 언어 링크를 제공합니다.",
+       "apihelp-parse-paramvalue-prop-categories": "구문 분석된 위키텍스트의 분류를 제공합니다.",
        "apihelp-parse-paramvalue-prop-categorieshtml": "분류의 HTML 버전을 제공합니다.",
        "apihelp-parse-paramvalue-prop-links": "구문 분석된 위키텍스트의 내부 링크를 제공합니다.",
        "apihelp-parse-paramvalue-prop-templates": "구문 분석된 위키텍스트의 틀을 제공합니다.",
        "apihelp-parse-paramvalue-prop-sections": "구문 분석된 위키텍스트의 문단을 제공합니다.",
        "apihelp-parse-paramvalue-prop-revid": "구문 분석된 페이지의 판 ID를 추가합니다.",
        "apihelp-parse-paramvalue-prop-displaytitle": "구문 분석된 위키텍스트의 제목을 추가합니다.",
+       "apihelp-parse-paramvalue-prop-headitems": "문서의 <code>&lt;head&gt;</code> 안에 넣을 항목을 제공합니다.",
+       "apihelp-parse-paramvalue-prop-headhtml": "문서의 구문 분석된 <code>&lt;head&gt;</code>를 제공합니다.",
        "apihelp-parse-paramvalue-prop-iwlinks": "구문 분석된 위키텍스트의 인터위키 링크를 제공합니다.",
        "apihelp-parse-paramvalue-prop-wikitext": "구문 분석된 위키텍스트 원문을 제공합니다.",
        "apihelp-parse-paramvalue-prop-properties": "구문 분석된 위키텍스트에 정의된 다양한 속성을 제공합니다.",
        "apihelp-query+blocks-param-ids": "나열할 차단 ID 목록 (선택 사항).",
        "apihelp-query+blocks-param-users": "검색할 사용자 목록 (선택 사항).",
        "apihelp-query+blocks-param-prop": "얻고자 하는 속성:",
+       "apihelp-query+blocks-paramvalue-prop-id": "블록의 ID를 추가합니다.",
        "apihelp-query+blocks-paramvalue-prop-user": "차단된 사용자의 사용자 이름을 추가합니다.",
        "apihelp-query+blocks-paramvalue-prop-userid": "차단된 사용자의 사용자 ID를 추가합니다.",
        "apihelp-query+blocks-paramvalue-prop-by": "차단을 수행하는 사용자의 사용자 이름을 추가합니다.",
        "api-help-permissions-granted-to": "{{PLURAL:$1|다음 그룹에 부여됨}}: $2",
        "api-help-open-in-apisandbox": "<small>[연습장에서 열기]</small>",
        "api-help-authmanagerhelper-messageformat": "반환 메시지에 사용할 형식.",
-       "api-credits": "API 개발자:\n* Roan Kattouw (선임 개발자, 2007년 9월–2009년)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (초기 개발자, 선임 개발자 2006년 9월~2007년 9월)\n* Brad Jorsch (선임 개발자 2013년–현재)\n\n당신의 의견이나 제안, 질문은 mediawiki-api@lists.wikimedia.org 로 보내주시거나,\nhttps://phabricator.wikimedia.org/ 에 버그 신고를 해 주시기 바랍니다.."
+       "api-credits": "API 개발자:\n* Roan Kattouw (선임 개발자, 2007년 9월–2009년)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (초기 개발자, 선임 개발자 2006년 9월~2007년 9월)\n* Brad Jorsch (선임 개발자 2013년–현재)\n\n당신의 의견이나 제안, 질문은 mediawiki-api@lists.wikimedia.org 로 보내주시거나,\nhttps://phabricator.wikimedia.org/ 에 버그 보고를 해 주시기 바랍니다."
 }
index 2376c7b..3c7c68d 100644 (file)
        "apihelp-imagerotate-param-rotation": "Öm wi vill Jrahd sulle de Bellder noh de Uhr drieh wääde?",
        "apihelp-imagerotate-example-simple": "Drieh de <kbd>Dattei:Beijschpell.png</kbd> öm <kbd>90</kbd> Jrahd.",
        "apihelp-imagerotate-example-generator": "Drieh alle Bellder en dä <kbd>Saachjropp:Ömdriehje</kbd> öm <kbd>180</kbd> Jrahd.",
-       "apihelp-import-param-summary": "Zersammefaßong för der Empohrt.",
+       "apihelp-import-param-summary": "Zersammefaßong för der Empohrt för et Logbohch.",
        "apihelp-import-param-xml": "Donn en Dattei em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Extensible Markup Language\">XML</i>-Fommaht huhjahde.",
        "apihelp-import-param-interwikisource": "För et Empottehre us enem andere Wikki: Dat Wikki vun woh der Empohrt kumme sull.",
        "apihelp-import-param-interwikipage": "För et Empottehre us enem andere Wikki: De Sigg zom Empottehre.",
        "apihelp-parse-paramvalue-prop-headitems": "Jitt de Saacher för enn der <code>&lt;head&gt;</code> vun dä Sigg ze donn.",
        "apihelp-parse-paramvalue-prop-modules": "Jitt dem <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Delivery system in MediaWiki for the optimized run-time loading and managing of modules\">ResourceLoader</i> sing Moduhle uß, di en dä Sigg jebruch wähde. Äntwehder „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">jsconfigvars</kbd>“ udder „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">encodedjsconfigvars</kbd>“ moß mer met „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">modules</kbd>“ zesamme aanforrdere.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "Livvert de Varrejahble vun dä Ennschtällonge vum JavaSkrep, di äxtra för heh di Sigg enjeschtallt sin.",
+       "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Livvert de Varrejahble vun dä Ennschtällonge vum JavaSkrep, di äxtra för heh di Sigg enjeschtallt sin als ene Täx em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"JavaScript Object Notation\">JSON</i>-Fommaht.",
        "apihelp-parse-paramvalue-prop-iwlinks": "Jitt de Engewikkilengks em jepahßde Wikkitäx uß.",
        "apihelp-parse-paramvalue-prop-wikitext": "Jitt de der ojinahl Wikkitäx us, dä jepahß woode es.",
        "apihelp-parse-paramvalue-prop-properties": "Jitt devärse Eijeschafte uß, di em jepahßde Wikkitäx faßjelaat woode sen.",
        "apihelp-protect-param-reason": "Der Jrond för et Schöze udder Freijävve.",
        "apihelp-protect-param-tags": "Donn de Makehronge aanpaße, dat se för dä Enndraach em Logbohch vum Sigge Schöze jehühre.",
        "apihelp-protect-param-cascade": "Donn en Schotz-Kaskahd zohlohße, alsu ene Schoz för ennjeföhschte Schablohne un upjerohfe Bellder vun dä Sigg. Deiht nix, wann keine von dä aanjejovve Zoote Schoz en Kaskahd zohlöht.",
+       "apihelp-protect-param-watchlist": "Donn di Sigg ohne Bedengonge op däm aktoälle Metmaacher sing Oppaßleß udder nemm se druß fott, donn de Enschtällonge nämme, udder donn de Oppaßleß jaa nit verändere.",
        "apihelp-protect-example-protect": "Donn en Sigg schöze.",
        "apihelp-purge-param-forcelinkupdate": "Bräng de Tabälle met de lengks obb ene neue Schtand.",
        "apihelp-purge-example-simple": "Donn fö de Sigge „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Main Page</kbd>“ un „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">API</kbd>“ de zweschejeschpeijscherte Väsjohn fottschmiiße.",
        "apihelp-query+allredirects-param-to": "De Övverschreff vun dä Sigg, woh et Zälle ophühre sull.",
        "apihelp-query+allredirects-param-prefix": "Söhk not Sigge, di esu aanfange.",
        "apihelp-query+allredirects-param-unique": "Zeijsch blohß de ongerscheidlijje Zihl_Sigg. Kam_mer nit zesamme met „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1prop=ids|fragment|interwiki</code>“ bruche. Wam_mer et als ene  Jenerahtor bruche deiht, kritt mer Zihlsiggge anschtatt vun Quällesigge.",
+       "apihelp-query+allredirects-param-prop": "Wat för en Aanjahbe ennschlehße:",
+       "apihelp-query+allredirects-paramvalue-prop-ids": "Deiht de Kännonge vun dä Ömleijdongssigg derbei. Kam_mer nit zersamme met „< var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1unique</var>“ bruche.",
        "apihelp-query+allredirects-paramvalue-prop-title": "Deiht dä Ömleijdong ehr Övverschreff derbei.",
        "apihelp-query+allredirects-param-namespace": "Dat Appachtemang zom opzälle.",
        "apihelp-query+allredirects-param-limit": "Wi vill sulle överhoup aanjezeisch wääde?",
        "apihelp-query+allusers-param-group": "Donn blohß Metmaacher uß dä aanjejovve Jroppe enschlehße.",
        "apihelp-query+allusers-param-excludegroup": "Donn keine Metmaacher uß dä aanjejovve Jroppe enschlehße.",
        "apihelp-query+allusers-param-prop": "Wat för en Aanjahbe med enzschlehße:",
+       "apihelp-query+allusers-paramvalue-prop-implicitgroups": "Donn alle Jroppe opleste, woh dä Metmaacher automattesch dren es.",
        "apihelp-query+allusers-paramvalue-prop-rights": "De Rääschde vn däm Memaacher.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "Donn de Aanzahl Änderonge derbei, di dä Metmaacher em Wikki jemaat hät.",
+       "apihelp-query+allusers-paramvalue-prop-registration": "Wann aanjejovve, deihd dat heh et Dattom un de Zigg derbei, wann dä Metmaacher sesch aanjemälld hät, wann müjjelech. Dat kann läddesch blihve.",
        "apihelp-query+allusers-param-limit": "Wi vill Nahme Metmaacher sulle mer krijje?",
        "apihelp-query+allusers-param-witheditsonly": "Blohß Metmahcher, di och ens jät verändert han.",
        "apihelp-query+allusers-param-activeusers": "Donn blohß Metmaacher opleßte, di  {{PLURAL:$1|der läzde Daach|en de läzde $1 Dääsch|keine läzde Daach}} aktihf wohre.",
        "apihelp-query+iwbacklinks-example-simple": "Holl Sigge, di op „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[wikibooks:Test]]</code>“ verlengke.",
        "apihelp-query+iwbacklinks-example-generator": "Holl Ennfommazjuhne övver Sigge, di op „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[wikibooks:Test]]</code>“ verlengke.",
        "apihelp-query+iwlinks-description": "Jiff alle Engerwikki_Lengks vun de aanjejovve Sigge uß.",
+       "apihelp-query+iwlinks-paramvalue-prop-url": "Deiht dä kumplätte <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Locator\">URL</i> derbei.",
        "apihelp-query+iwlinks-param-limit": "Wi vill Engerwikki_Lengks zem ußjävve?",
        "apihelp-query+iwlinks-param-prefix": "Jiff blohß de Engerwikki_Lengks uß, di dermet aanfange.",
+       "apihelp-query+iwlinks-param-title": "Dä Engerwiki Lengk för dernoh ze söhke. Moß met <var>$1prefix</var> zesamme jebruch wähde.",
        "apihelp-query+iwlinks-param-dir": "En wälsche Reihjefollsch opleßte.",
        "apihelp-query+langbacklinks-param-lang": "Schprohch för dä Schprohche_Lengk.",
        "apihelp-query+langbacklinks-param-title": "Der Schprohche_Lengk för noh ze söhke. Moß zersamme met <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1lang</code> jebruch wähde.",
        "apihelp-query+langbacklinks-param-limit": "Wi vill Sigge ensjesammp zem ußjävve?",
+       "apihelp-query+langbacklinks-param-prop": "Wat för en Prijoretähte holle:",
+       "apihelp-query+langbacklinks-paramvalue-prop-lllang": "Deiht de Kännong för de Schprohch för dä Schprohchelengk derbei.",
+       "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Deiht de Övverschreff för dä Schprohchelengk derbei.",
        "apihelp-query+langbacklinks-param-dir": "En wälsche Reihjefollsch opleßte.",
        "apihelp-query+langbacklinks-example-simple": "Holl Sigge, di op „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[:fr:Test]]</code>“ verlengke.",
        "apihelp-query+langbacklinks-example-generator": "Holl Ennfommazjuhne övver Sigge, di op „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[:fr:Test]]</code>“ verlengke.",
        "apihelp-query+langlinks-description": "Jiff alle Schprohche_Lengks vun de aanjejovve Sigge uß.",
        "apihelp-query+langlinks-param-limit": "Wi vill Schprohche_Lengks holle?",
+       "apihelp-query+langlinks-paramvalue-prop-url": "Deiht dä kumplätte <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Locator\">URL</i> derbei.",
+       "apihelp-query+langlinks-paramvalue-prop-autonym": "Deiht dä Nahme vun de Moterschprohch derbei.",
        "apihelp-query+langlinks-param-lang": "Donn blohß de Schprohche_Lengks met däm aanjejovve Schprohche_Köözel.",
        "apihelp-query+langlinks-param-dir": "En wälsche Reihjefollsch opleßte.",
        "apihelp-query+links-description": "Jiff alle Lengks vun de aanjejovve Sigge uß.",
+       "apihelp-query+links-param-namespace": "Zeijsch blohß de Lengks en dä Appachtemangs.",
        "apihelp-query+links-param-limit": "Wi vill Lengks ußjävve?",
        "apihelp-query+links-param-titles": "Donn blohß e Lengks of heh di Övverschreffte opleßte. Dadd es johd, öm eruß ze fenge ovv en en beschtemmpte Sigg op ene beschtemmpte Övverschreff verlengk es.",
        "apihelp-query+links-param-dir": "En wälsche Reihjefollsch opleßte.",
+       "apihelp-query+links-example-simple": "Holl de Lengks vun dä Sigg <kbd>Main Page</kbd>",
        "apihelp-query+linkshere-description": "Fengk alle Sigge, di op de aanjejovve Sigge lengke.",
        "apihelp-query+linkshere-param-prop": "Wat för en Eijeschaffte holle:",
        "apihelp-query+linkshere-paramvalue-prop-pageid": "Page ID of each page.",
        "apihelp-query+linkshere-example-simple": "Holl en Leß vun Sigge, di op de Sigg „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[Main Page]]</code>“ lengke donn.",
        "apihelp-query+linkshere-example-generator": "Holl Ennfommazjuhne övver Sigge, di op de Sigg „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[Main Page]]</code>“ lengke.",
        "apihelp-query+logevents-description": "Holl Enndrähsch us de Logböhscher.",
+       "apihelp-query+logevents-param-prop": "Wat för en Eijeschaffte holle:",
        "apihelp-query+logevents-param-type": "Söhk blohß heh di Zood Enndrähsch us de Logböhscher.",
        "apihelp-query+logevents-param-start": "Et Dattom un de Zigg vun woh aff opjezallt wähde sull.",
        "apihelp-query+logevents-param-end": "Dattum un Uhrzigg, bes wann opzälle.",
        "apihelp-query+pageprops-description": "Jitt devärse Eijeschafte uß, di em Ennhald vun dä Sigg faßjelaat wohde sen.",
        "apihelp-query+pageprops-example-simple": "Holl de Eijeschaffte för di Sigge „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Main Page</kbd>“ un „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">MediaWiki</kbd>“.",
        "apihelp-query+pageswithprop-description": "Donn alle Sigge met bechtemmpte Sigge_Eijeschaff opleßte.",
+       "apihelp-query+pageswithprop-param-prop": "Wat för en Aanjahbe ennschlehße:",
        "apihelp-query+pageswithprop-paramvalue-prop-ids": "Deiht de Kännong vun de Sigge derbei.",
+       "apihelp-query+pageswithprop-paramvalue-prop-title": "Donn de Övverschrevv un de Kännong för di Sigg derbei.",
        "apihelp-query+pageswithprop-paramvalue-prop-value": "Deiht der Wäät för de Eijeschaff vun dä Sigg derbei.",
        "apihelp-query+pageswithprop-param-limit": "De jrüüßte Zahl Sigge för ußzejävve.",
        "apihelp-query+pageswithprop-param-dir": "En wälsche Reihjefollsch opleßte.",
        "apihelp-query+recentchanges-description": "Donn de  neußte Änderonge opleßte.",
        "apihelp-query+recentchanges-param-start": "Et Dattom un de Zigg vun woh aff opjezallt wähde sull.",
        "apihelp-query+recentchanges-param-end": "Dattum un Uhrzigg, bes wann opzälle.",
+       "apihelp-query+recentchanges-param-namespace": "Donn de Änderonge blohß us de aanjejovve Appachtemans nämme.",
        "apihelp-query+recentchanges-param-user": "Donn blohß Änderonge vun heh däm Metmaacher opleßte.",
        "apihelp-query+recentchanges-param-excludeuser": "Donn kein Änderonge vun heh däm Metmaacher opleßte.",
        "apihelp-query+recentchanges-param-tag": "Donn blohß Änderonge met heh dä Makkehrong opleßte.",
+       "apihelp-query+recentchanges-param-prop": "Donn zohsäzlejje Aanjahbe ennschlehße:",
+       "apihelp-query+recentchanges-paramvalue-prop-flags": "Deihd de Makkehronge vun dä Änderong derbei.",
+       "apihelp-query+recentchanges-paramvalue-prop-timestamp": "Deihd et Dattom un de Uhrzigg vun dä Änderong derbei.",
+       "apihelp-query+recentchanges-paramvalue-prop-title": "Deihd de neuje Övverschreff noh dä Änderong derbei.",
        "apihelp-query+recentchanges-paramvalue-prop-tags": "Donn de Makkehronge för dä Enndraach opleßte.",
        "apihelp-query+recentchanges-paramvalue-prop-sha1": "Donn de Pröhvsom för di Enndrähsch oplesßte, di met enne Väsjohn zesamme hange.",
        "apihelp-query+recentchanges-param-token": "Nemm „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>“ schtatt dämm.",
        "apihelp-query+revisions+base-paramvalue-prop-userid": "Däm Metmaacher sing Kännong, dä di Väsjohn aanjelaat hät.",
        "apihelp-query+revisions+base-paramvalue-prop-size": "Der Ömvang en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Bytes</i> vun dä Väsjohn.",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "De <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"secure hash algorithm\">SHA-1 (base 16)</i> Prööfsomm vun dä Väsjohn.",
-       "apihelp-query+revisions+base-paramvalue-prop-comment": "De Aanmärkong vum Metmaacher för di äsjohn.",
+       "apihelp-query+revisions+base-paramvalue-prop-comment": "De Aanmärkong vum Metmaacher för di Väsjohn.",
+       "apihelp-query+revisions+base-paramvalue-prop-parsedcomment": "De jepaaste Aanmärkong vum Metmaacher för di Väsjohn.",
        "apihelp-query+revisions+base-paramvalue-prop-content": "Der Täx vun dä Väsjohn.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Makkehronge vun dä Väsjohn.",
        "apihelp-query+revisions+base-param-limit": "Wi vill Väsjohne sulle ußjejovve wähde?",
        "apihelp-query+search-param-what": "Wat för en Aat ze Söhke?",
        "apihelp-query+search-param-info": "Wat för en Metta_Dahte ußzejävve.",
        "apihelp-query+search-param-prop": "Wat för en Eijeschaffte holle:",
+       "apihelp-query+search-paramvalue-prop-wordcount": "Deiht de Aanzahl Wööter en dä Sigg derbeij.",
+       "apihelp-query+search-paramvalue-prop-timestamp": "Deihd et Dattum un de Uhrzigg derbei, wann di Sigg et läz veränndert wohd.",
+       "apihelp-query+search-paramvalue-prop-redirecttitle": "Deiht dä zopaß Ömleijdong ehr Övverschreff derbei.",
        "apihelp-query+search-param-limit": "Wi vill Sigge ensjesamp ußjävve?",
        "apihelp-query+search-param-interwiki": "Donn de Engerwiki Lengks met ußjävve beim Söhke, wann_er doh sin.",
        "apihelp-query+search-example-simple": "Söhk noh „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">meaning</kbd>“.",
        "apihelp-query+search-example-text": "Söhk en Täxte noh „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">meaning</kbd>“.",
        "apihelp-query+search-example-generator": "Holl anjahbe övver di Sigge, di jefonge wähde beim söhke noh \n„<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">meaning</kbd>“",
        "apihelp-query+siteinfo-description": "Jiff alljemeine Ennfommazjuhne övver heh di ẞaid_uß.",
+       "apihelp-query+siteinfo-param-prop": "Wat för en Ennfommazjuhne holle:",
+       "apihelp-query+siteinfo-paramvalue-prop-general": "Alljemeine Aanjabe zom Süßtehm.",
+       "apihelp-query+siteinfo-paramvalue-prop-statistics": "Jivv Schtatistike vum Wikki uß.",
+       "apihelp-query+siteinfo-paramvalue-prop-variables": "Jid en Leß med de verföhschbahre Kännonge us.",
        "apihelp-query+siteinfo-param-filteriw": "Donn blohß de Enndrähsch för heh et Wikki udder blohß de Enndrähsch för ußerhallef en di Leß.",
        "apihelp-query+siteinfo-param-showalldb": "Donn alle ẞööver för de Dahtebangke opleßte, nit blohß di am mihßte hengerher sin.",
        "apihelp-query+siteinfo-param-numberingroup": "Donn de Aanzahl Metmaacher en de Jroppe vun Metmaacher opleßte.",
        "apihelp-query+usercontribs-paramvalue-prop-ids": "Donn de Kännong för jehde Sigg un jehe Väsjohn derbei.",
        "apihelp-query+usercontribs-paramvalue-prop-title": "Donn de Övverschrevv un de Kännong för et Appachtemang derbei.",
        "apihelp-query+usercontribs-paramvalue-prop-timestamp": "Deihd et Dattom un de Uhrzigg vun dä Änderong derbei.",
+       "apihelp-query+usercontribs-paramvalue-prop-comment": "Deihd de Zosammefaßong vun dä Änderong derbei.",
+       "apihelp-query+usercontribs-paramvalue-prop-parsedcomment": "Deihd de jepaaste Zosammefaßong vun dä Änderong derbei.",
        "apihelp-query+usercontribs-paramvalue-prop-size": "Deihd de neuje Jrühße noh dä Änderong derbei.",
        "apihelp-query+usercontribs-paramvalue-prop-sizediff": "Deihd de Änderong vun dä Jrühße vun dä Änderong derbei.",
        "apihelp-query+usercontribs-paramvalue-prop-flags": "Deihd de Makkehronge vun dä Änderong derbei.",
+       "apihelp-query+usercontribs-paramvalue-prop-patrolled": "Nohjelohrte Änderonge makkehre.",
        "apihelp-query+usercontribs-paramvalue-prop-tags": "Donn de Makkehronge vun dä Änderong opleßte.",
        "apihelp-query+usercontribs-param-tag": "Donn blohß Väsjohne met heh dä Makehrong opleßte.",
        "apihelp-query+usercontribs-param-toponly": "Bloß Änderonge aanzeije, woh de neußte Väsjohn beij eruß kohm.",
        "apihelp-query+userinfo-example-data": "Holl zohsäzlejje Aanjahbe övver dä aktoälle Metmaacher.",
        "apihelp-query+users-description": "Holl Aanjahbe övver en Leß vun Metmaacher.",
        "apihelp-query+users-param-prop": "Wat för en Aanjahbe med enzschlehße:",
+       "apihelp-query+users-paramvalue-prop-groups": "Donn alle Jroppe opleßte, woh all de Metmaacher dren sin.",
+       "apihelp-query+users-paramvalue-prop-implicitgroups": "Donn alle Jroppe opleßte, woh ene Metmaacher aotomattesch dren es.",
        "apihelp-query+users-paramvalue-prop-rights": "Donn alle Rääschte opleßte, di alle Metmaacher han.",
        "apihelp-query+users-paramvalue-prop-editcount": "Donn däm Metmaacher sing Aanzahl Ännderonge derbeij.",
        "apihelp-query+users-paramvalue-prop-registration": "Donn et Dattom vun dämm Metmaacher singe eetze Aanmäldong derbei.",
        "apihelp-query+watchlist-paramvalue-prop-flags": "Deihd de Makkehronge vun dä Änderong derbei.",
        "apihelp-query+watchlist-paramvalue-prop-user": "Deiht dä Metmaacher derbei, dä di Änderong jemaat hät.",
        "apihelp-query+watchlist-paramvalue-prop-userid": "Deiht de kännong vn äm Metmaacher derbei, dä di Änderong jemaat hät.",
+       "apihelp-query+watchlist-paramvalue-prop-comment": "Deihd de Zosammefaßong vun dä Änderong derbei.",
+       "apihelp-query+watchlist-paramvalue-prop-parsedcomment": "Deihd de jepaaste Zosammefaßong vun dä Änderong derbei.",
        "apihelp-query+watchlist-paramvalue-prop-timestamp": "Deihd et Dattom un de Uhrzigg vun dä Änderong derbei.",
+       "apihelp-query+watchlist-paramvalue-prop-patrol": "Makkehrt de nohjelohrte Ännderonge.",
+       "apihelp-query+watchlist-paramvalue-prop-sizes": "Deiht de vörrijje un de neuje Läng vun dä Sigg derbei.",
        "apihelp-query+watchlist-param-type": "Wat för en Änderonge aanzeije:",
        "apihelp-query+watchlist-paramvalue-type-edit": "Jewöhnlejje Ännderonge aan Sigge.",
        "apihelp-query+watchlist-paramvalue-type-external": "Änderonge vun Ußerhallef.",
        "apihelp-query+watchlistraw-param-namespace": "Donn blohß Sigge en heh däm Appachtemang opleßte.",
        "apihelp-query+watchlistraw-param-limit": "Wi vell Äjehbneße ennsjesammp pro Oprohv ußjejovve wähde sulle.",
        "apihelp-query+watchlistraw-param-prop": "Wat för en zohsäzlejje Eijeschaffte holle:",
+       "apihelp-query+watchlistraw-param-dir": "En wälsche Reihjefollsch opleßte.",
        "apihelp-query+watchlistraw-example-simple": "Donn alle Sigge uß dem aktälle Metmaacher sing Oppaßleß opleßte.",
        "apihelp-removeauthenticationdata-example-simple": "Versöhk dem aktoäle Metmaacher sing Dahte för <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">FooAuthenticationRequest</kbd> fott ze nämme.",
        "apihelp-resetpassword-example-email": "Schegg en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> mem Passwod neu säze aan alle Matmaacher met dä Addräß <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">user@example.com</kbd>.",
        "apihelp-tag-example-log": "Donn de Makkehrong „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">spam</kbd>“ vun dämm Enndrahch met dä Kännong „<kbd>123</kbd>“ em Logbohch fott nämme un als Jrond draaach „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Wrongly applied</kbd>“ enn.",
        "apihelp-unblock-description": "Don en Schpärr för ene Metmaacher ophävve.",
        "apihelp-unblock-param-reason": "Der Jrond för de Schpärr opzehävve.",
+       "apihelp-unblock-param-tags": "Donn de Makehronge änndere, di för dä Enndraach em Logbohch vum Schpärre jesaz wähde sulle.",
        "apihelp-undelete-param-title": "De Övverschreff vun dä Sigg zom zerök holle.",
        "apihelp-undelete-param-reason": "Der Jrond för et Zerök holle.",
        "apihelp-undelete-param-tags": "Donn de Makehronge aanpaße, dat se för dä Enndraach em Logbohch vum Sigge fott Schmihße jehühre.",
        "api-help-param-default": "Schtandatt: $1",
        "api-help-param-default-empty": "Schtandatt: <span class=\"apihelp-empty\">(läddesch)</span>",
        "api-help-param-disabled-in-miser-mode": "Dadd es wäje em [[mw:Manual:$wgMiserMode|miser mode]] affjeschalldt.",
-       "api-help-param-limited-in-miser-mode": "<strong>opjepaß:</strong> Weil der  [[mw:Manual:$wgMiserMode|miser mode]] enjeschalld es, künne heh winnijer wi <var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1limit</var> Äjehpneße ußjejejovve wähde, vör em Wigger_Mache. En Jränzfäll künne et Noll sin.",
+       "api-help-param-limited-in-miser-mode": "<strong>Opjepaß:</strong> Weil der [[mw:Manual:$wgMiserMode|miser mode]] enjeschalld es, künne heh winnijer wi <var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1limit</var> Äjehpneße ußjejejovve wähde, vör em Wigger_Mache. En Jränzfäll künne et Noll sin.",
        "api-help-param-direction": "En wälsche Reihjefollsch opleßte:\n;<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">newer</code>:De Ählsde et eez. Opjepaß: „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1start</code>“ moß fröhjer sin wi „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1end</code>“.\n;<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">older</code>:De Neuste et eez, der Schtanndatt. Opjepaß: „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1start</code>“ moß schpääder sin wi „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1end</code>“.",
        "api-help-param-continue": "Wann mih ze holle es, nemm dat för wigger ze maache.",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(nix drövver bikannt)</span>",
index 12ec506..be09192 100644 (file)
@@ -21,6 +21,9 @@
        "apihelp-emailuser-param-target": "Bikarhênerê ku e-name jê rê bê şandin.",
        "apihelp-expandtemplates-param-title": "Sernavê rûpelê.",
        "apihelp-feedcontributions-param-deletedonly": "Tenê beşdariyên jêbirî nîşan bide.",
+       "apihelp-feedcontributions-param-hideminor": "Guherandinên biçûk veşêre.",
+       "apihelp-feedrecentchanges-param-hideminor": "Guherandinên biçûk veşêre.",
+       "apihelp-feedrecentchanges-param-hidebots": "Guherandinên botan veşêre.",
        "apihelp-feedrecentchanges-example-simple": "Guherandinên dawî nîşan bide.",
        "apihelp-feedrecentchanges-example-30days": "Guherandinên dawî yên 30 rojan nîşan bide",
        "apihelp-filerevert-param-comment": "Şîroveyê bar bike.",
@@ -35,5 +38,7 @@
        "apihelp-parse-example-summary": "Kurteyekê analîz bike",
        "apihelp-protect-description": "Asta parastinê ya rûpelekê biguherîne.",
        "apihelp-protect-example-protect": "Rûpelekê biparêze.",
-       "apihelp-tag-param-reason": "Sedemê bo guherandinê."
+       "apihelp-query+alllinks-paramvalue-prop-title": "Sernavê girêdanê lê zêde dike.",
+       "apihelp-tag-param-reason": "Sedemê bo guherandinê.",
+       "api-help-parameters": "{{PLURAL:$1|Parametre}}:"
 }
index 89fa617..c2545fc 100644 (file)
@@ -45,6 +45,7 @@
        "apihelp-query+watchlist-paramvalue-prop-title": "د يو مخ سرليک ورگډوي.",
        "apihelp-query+watchlist-paramvalue-type-new": "مخ جوړونې.",
        "apihelp-stashedit-param-sectiontitle": "د يوې نوې برخې سرليک.",
+       "apihelp-stashedit-param-summary": "د بدلون لنډيز.",
        "apihelp-tag-param-reason": "د بدلون سبب.",
        "apihelp-unblock-param-reason": "د بنديز ليرې کولو سبب.",
        "apihelp-undelete-param-reason": "د بيازېرملو سبب.",
index d99945d..517496f 100644 (file)
@@ -24,7 +24,7 @@
        "apihelp-main-param-requestid": "Будь-яке значення, вказане тут, буде включене у відповідь. Може використовуватися, щоб відрізняти запити.",
        "apihelp-main-param-servedby": "Включити в результати ім'я хоста, який обробив запит.",
        "apihelp-main-param-curtimestamp": "Включити в результат поточну мітку часу.",
-       "apihelp-main-param-origin": "При доступі до API з використанням крос-доменного AJAX-запиту (CORS), задайте параметру значення вихідного домена. Він має бути включений у будь-який попередній запит і таким чином мусить бути частиною запиту URI (не тіла POST). Він повинен точно співпадати з одним з виходів у заголовку <code>Origin</code>, тобто бути заданим чимось на зразок <kbd>https://uk.wikipedia.org</kbd> або <kbd>https://meta.wikimedia.org</kbd>. Якщо цей параметр не співпадає з заголовком <code>Origin</code>, повернеться помилка 403. Якщо цей параметр співпадає з заголовком <code>Origin</code> і вихід знаходиться у білому списку, буде встановлено заголовок <code>Access-Control-Allow-Origin</code>.",
+       "apihelp-main-param-origin": "При доступі до API з використанням крос-доменного AJAX-запиту (CORS), задайте параметру значення вихідного домена. Він має бути включений у будь-який попередній запит і таким чином мусить бути частиною запиту URI (не тіла POST). \n\nДля автентифікованих запитів він повинен точно співпадати з одним з виходів у заголовку <code>Origin</code>, тобто бути заданим чимось на зразок <kbd>https://uk.wikipedia.org</kbd> або <kbd>https://meta.wikimedia.org</kbd>. Якщо цей параметр не співпадає з заголовком <code>Origin</code>, повернеться помилка 403. Якщо цей параметр співпадає з заголовком <code>Origin</code> і вихід знаходиться у білому списку, буде встановлено заголовки <code>Access-Control-Allow-Origin</code> і <code>Access-Control-Allow-Credentials</code>.\n\nДля неавтентифікованих запитів укажіть значення <kbd>*</kbd>. Це дасть встановлення заголовка <code>Access-Control-Allow-Origin</code>, але <code>Access-Control-Allow-Credentials</code> буде <code>false</code> і всі дані про користувача будуть заборонені.",
        "apihelp-main-param-uselang": "Мова, що використовується для перекладу повідомлень. Список кодів можна видати на <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> з <kbd>siprop=languages</kbd> або вказати <kbd>user</kbd> на використання поточного налаштування мови користувача, або вказати <kbd>content</kbd> на використання мови вмісту цієї вікі.",
        "apihelp-block-description": "Заблокувати користувача.",
        "apihelp-block-param-user": "Ім'я користувача, IP-адреса або діапазон IP-адрес для блокування.",
@@ -74,6 +74,7 @@
        "apihelp-createaccount-param-language": "Код мови для встановлення за замовчуванням для користувача (необов'язково, за замовчуванням — мова вмісту).",
        "apihelp-createaccount-example-pass": "Створити користувача <kbd>testuser</kbd> з паролем <kbd>test123</kbd>.",
        "apihelp-createaccount-example-mail": "Створити користувача <kbd>testmailuser</kbd> і надіслати на електронну пошту випадково-згенерований пароль.",
+       "apihelp-cspreport-description": "Використовується браузерами для повідомлення порушень Правил безпеки контенту (Content Security Policy). Цей модуль не повинен використовуватися, окрім випадків автоматичного використання веб-браузером для CSP-скарги.",
        "apihelp-delete-description": "Вилучити сторінку.",
        "apihelp-delete-param-title": "Назва сторінки для вилучення. Не можна використати разом з <var>$1pageid</var>.",
        "apihelp-delete-param-pageid": "ID-сторінки на вилучення. Не можна використати разом з <var>$1title</var>.",
index 6b697dc..c60976f 100644 (file)
@@ -33,7 +33,7 @@
        "apihelp-main-param-requestid": "任何在此提供的值将包含在响应中。可能可以用以区别请求。",
        "apihelp-main-param-servedby": "包含保存结果请求的主机名。",
        "apihelp-main-param-curtimestamp": "在结果中包括当前时间戳。",
-       "apihelp-main-param-origin": "当通过跨域名AJAX请求(CORS)访问API时,设置此作为起始域名。这必须包括在任何pre-flight请求中,并因此必须是请求的URI的一部分(而不是POST正文)。这必须匹配<code>Origin</code>中的一个起点:从头到底,因此它已经设置为像<kbd>https://zh.wikipedia.org</kbd>或<kbd>https://meta.wikimedia.org</kbd>的东西。如果此参数不匹配<code>Origin</code>页顶,就返回403错误响应。如果此参数匹配<code>Origin</code>页顶并且起点被白名单,将设置一个<code>Access-Control-Allow-Origin</code>开头。",
+       "apihelp-main-param-origin": "当通过跨域名AJAX请求(CORS)访问API时,设置此作为起始域名。这必须包括在任何pre-flight请求中,并因此必须是请求的URI的一部分(而不是POST正文)。\n\n对于已验证的请求,这必须正确匹配<code>Origin</code>标头中的原点之一,因此它已经设置为像<kbd>https://zh.wikipedia.org</kbd>或<kbd>https://meta.wikimedia.org</kbd>的东西。如果此参数不匹配<code>Origin</code>页顶,就返回403错误响应。如果此参数匹配<code>Origin</code>页顶并且起点被白名单,将设置<code>Access-Control-Allow-Origin</code>和<code>Access-Control-Allow-Credentials</code>开头。\n\n对于未验证的请求,会指定值<kbd>*</kbd>。这将导致<code>Access-Control-Allow-Origin</code>标头被设置,但<code>Access-Control-Allow-Credentials</code>将为<code>false</code>,且所有用户特定数据将受限制。",
        "apihelp-main-param-uselang": "用于消息翻译的语言。<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>与<kbd>siprop=languages</kbd>可返回语言代码列表,或指定<kbd>user</kbd>以使用当前用户的语言设置,或指定<kbd>content</kbd>以使用此wiki的内容语言。",
        "apihelp-block-description": "封禁一位用户。",
        "apihelp-block-param-user": "您要封禁的用户、IP地址或IP地址段。",
index 6db5f2c..82eeff0 100644 (file)
@@ -1695,6 +1695,10 @@ class AuthManager implements LoggerAwareInterface {
                        $logid = $logEntry->insert();
                }
 
+               // Commit database changes, so even if something else later blows up
+               // the newly-created user doesn't get lost.
+               wfGetLBFactory()->commitMasterChanges( __METHOD__ );
+
                if ( $login ) {
                        $this->setSessionDataForUser( $user );
                }
index 8d85b44..8845858 100644 (file)
@@ -161,35 +161,13 @@ class AuthManagerAuthPlugin extends \AuthPlugin {
        }
 
        public function addUser( $user, $password, $email = '', $realname = '' ) {
-               global $wgUser;
-
-               $data = [
-                       'username' => $user->getName(),
-                       'password' => $password,
-                       'retype' => $password,
-                       'email' => $email,
-                       'realname' => $realname,
-               ];
-               if ( $this->domain !== null && $this->domain !== '' ) {
-                       $data['domain'] = $this->domain;
-               }
-               $reqs = AuthManager::singleton()->getAuthenticationRequests( AuthManager::ACTION_CREATE );
-               $reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
-
-               $res = AuthManager::singleton()->beginAccountCreation( $wgUser, $reqs, 'null:' );
-               switch ( $res->status ) {
-                       case AuthenticationResponse::PASS:
-                               return true;
-                       case AuthenticationResponse::FAIL:
-                               // Hope it's not a PreAuthenticationProvider that failed...
-                               $msg = $res->message instanceof \Message ? $res->message : new \Message( $res->message );
-                               $this->logger->info( __METHOD__ . ': Authentication failed: ' . $msg->plain() );
-                               return false;
-                       default:
-                               throw new \BadMethodCallException(
-                                       'AuthManager does not support such simplified account creation'
-                               );
-               }
+               throw new \BadMethodCallException(
+                       'Creation of users via AuthPlugin is not supported with '
+                       . 'AuthManager. Generally, user creation should be left to either '
+                       . 'Special:CreateAccount, auto-creation when triggered by a '
+                       . 'SessionProvider or PrimaryAuthenticationProvider, or '
+                       . 'User::newSystemUser().'
+               );
        }
 
        public function strict() {
index 4a0f566..d3a414b 100644 (file)
@@ -358,8 +358,7 @@ class EnhancedChangesList extends ChangesList {
        protected function getLineData( array $block, RCCacheEntry $rcObj, array $queryParams = [] ) {
                $RCShowChangedSize = $this->getConfig()->get( 'RCShowChangedSize' );
 
-               # Classes to apply -- TODO implement
-               $classes = [];
+               $classes = [ 'mw-enhanced-rc' ];
                $type = $rcObj->mAttribs['rc_type'];
                $data = [];
                $lineParams = [];
@@ -367,7 +366,7 @@ class EnhancedChangesList extends ChangesList {
                if ( $rcObj->watched
                        && $rcObj->mAttribs['rc_timestamp'] >= $rcObj->watched
                ) {
-                       $lineParams['classes'] = [ 'mw-enhanced-watched' ];
+                       $classes = [ 'mw-enhanced-watched' ];
                }
 
                $separator = ' <span class="mw-changeslist-separator">. .</span> ';
@@ -462,6 +461,8 @@ class EnhancedChangesList extends ChangesList {
                        unset( $data['timestampLink'] );
                }
 
+               $lineParams['classes'] = array_values( $classes );
+
                // everything else: makes it easier for extensions to add or remove data
                $lineParams['data'] = array_values( $data );
 
index 27f917b..c2e8b24 100644 (file)
@@ -93,7 +93,14 @@ class IcuCollation extends Collation {
                'be-tarask' => [ "Ё" ],
                'cy' => [ "Ch", "Dd", "Ff", "Ng", "Ll", "Ph", "Rh", "Th" ],
                'en' => [],
-               'fa' => [ "آ", "ء", "ه" ],
+               // RTL, let's put each letter on a new line
+               'fa' => [
+                       "آ",
+                       "ء",
+                       "ه",
+                       "ا",
+                       "و"
+               ],
                'fi' => [ "Å", "Ä", "Ö" ],
                'fr' => [],
                'hu' => [ "Cs", "Dz", "Dzs", "Gy", "Ly", "Ny", "Ö", "Sz", "Ty", "Ü", "Zs" ],
@@ -444,6 +451,13 @@ class IcuCollation extends Collation {
                $versionPrefix = substr( $icuVersion, 0, 3 );
                // Source: http://site.icu-project.org/download
                $map = [
+                       '57.' => '8.0',
+                       '56.' => '8.0',
+                       '55.' => '7.0',
+                       '54.' => '7.0',
+                       '53.' => '6.3',
+                       '52.' => '6.3',
+                       '51.' => '6.2',
                        '50.' => '6.2',
                        '49.' => '6.1',
                        '4.8' => '6.0',
index 86f0d50..4e8f0df 100644 (file)
@@ -127,7 +127,8 @@ class WikitextContentHandler extends TextContentHandler {
 
                $fields['opening_text'] =
                        $engine->makeSearchFieldMapping( 'opening_text', SearchIndexField::INDEX_TYPE_TEXT );
-               $fields['opening_text']->setFlag( SearchIndexField::FLAG_SCORING );
+               $fields['opening_text']->setFlag( SearchIndexField::FLAG_SCORING |
+                                                 SearchIndexField::FLAG_NO_HIGHLIGHT );
 
                $fields['outgoing_link'] =
                        $engine->makeSearchFieldMapping( 'outgoing_link', SearchIndexField::INDEX_TYPE_KEYWORD );
index cfdf382..9b73584 100644 (file)
@@ -2460,7 +2460,7 @@ abstract class DatabaseBase implements IDatabase {
        final public function onTransactionIdle( callable $callback ) {
                $this->mTrxIdleCallbacks[] = [ $callback, wfGetCaller() ];
                if ( !$this->mTrxLevel ) {
-                       $this->runOnTransactionIdleCallbacks();
+                       $this->runOnTransactionIdleCallbacks( self::TRIGGER_IDLE );
                }
        }
 
@@ -2475,9 +2475,10 @@ abstract class DatabaseBase implements IDatabase {
        /**
         * Actually any "on transaction idle" callbacks.
         *
+        * @param integer $trigger IDatabase::TRIGGER_* constant
         * @since 1.20
         */
-       protected function runOnTransactionIdleCallbacks() {
+       protected function runOnTransactionIdleCallbacks( $trigger ) {
                $autoTrx = $this->getFlag( DBO_TRX ); // automatic begin() enabled?
 
                $e = $ePrior = null; // last exception
@@ -2492,7 +2493,7 @@ abstract class DatabaseBase implements IDatabase {
                                try {
                                        list( $phpCallback ) = $callback;
                                        $this->clearFlag( DBO_TRX ); // make each query its own transaction
-                                       call_user_func( $phpCallback );
+                                       call_user_func_array( $phpCallback, [ $trigger ] );
                                        if ( $autoTrx ) {
                                                $this->setFlag( DBO_TRX ); // restore automatic begin()
                                        } else {
@@ -2520,9 +2521,11 @@ abstract class DatabaseBase implements IDatabase {
        /**
         * Actually any "on transaction pre-commit" callbacks.
         *
+        * This method should not be used outside of Database/LoadBalancer
+        *
         * @since 1.22
         */
-       protected function runOnTransactionPreCommitCallbacks() {
+       public function runOnTransactionPreCommitCallbacks() {
                $e = $ePrior = null; // last exception
                do { // callbacks may add callbacks :)
                        $callbacks = $this->mTrxPreCommitCallbacks;
@@ -2561,12 +2564,12 @@ abstract class DatabaseBase implements IDatabase {
 
        final public function endAtomic( $fname = __METHOD__ ) {
                if ( !$this->mTrxLevel ) {
-                       throw new DBUnexpectedError( $this, 'No atomic transaction is open.' );
+                       throw new DBUnexpectedError( $this, "No atomic transaction is open (got $fname)." );
                }
                if ( !$this->mTrxAtomicLevels ||
                        array_pop( $this->mTrxAtomicLevels ) !== $fname
                ) {
-                       throw new DBUnexpectedError( $this, 'Invalid atomic section ended.' );
+                       throw new DBUnexpectedError( $this, "Invalid atomic section ended (got $fname)." );
                }
 
                if ( !$this->mTrxAtomicLevels && $this->mTrxAutomaticAtomic ) {
@@ -2606,7 +2609,7 @@ abstract class DatabaseBase implements IDatabase {
                        } else {
                                // The transaction was automatic and has done write operations
                                if ( $this->mTrxDoneWrites ) {
-                                       wfDebug( "$fname: Automatic transaction with writes in progress" .
+                                       wfLogDBError( "$fname: Automatic transaction with writes in progress" .
                                                " (from {$this->mTrxFname}), performing implicit commit!\n"
                                        );
                                }
@@ -2621,7 +2624,7 @@ abstract class DatabaseBase implements IDatabase {
                                        $this->mServer, $this->mDBname, $this->mTrxShortId, $writeTime );
                        }
 
-                       $this->runOnTransactionIdleCallbacks();
+                       $this->runOnTransactionIdleCallbacks( self::TRIGGER_COMMIT );
                }
 
                // Avoid fatals if close() was called
@@ -2697,7 +2700,7 @@ abstract class DatabaseBase implements IDatabase {
                                $this->mServer, $this->mDBname, $this->mTrxShortId, $writeTime );
                }
 
-               $this->runOnTransactionIdleCallbacks();
+               $this->runOnTransactionIdleCallbacks( self::TRIGGER_COMMIT );
        }
 
        /**
@@ -2737,7 +2740,7 @@ abstract class DatabaseBase implements IDatabase {
 
                $this->mTrxIdleCallbacks = []; // clear
                $this->mTrxPreCommitCallbacks = []; // clear
-               $this->runOnTransactionIdleCallbacks();
+               $this->runOnTransactionIdleCallbacks( self::TRIGGER_ROLLBACK );
        }
 
        /**
index 3ebc3ec..02a8d30 100644 (file)
@@ -36,6 +36,8 @@ abstract class DatabaseMysqlBase extends Database {
        protected $lagDetectionMethod;
        /** @var array Method to detect slave lag */
        protected $lagDetectionOptions = [];
+       /** @var bool bool Whether to use GTID methods */
+       protected $useGTIDs = false;
 
        /** @var string|null */
        private $serverVersion = null;
@@ -43,13 +45,14 @@ abstract class DatabaseMysqlBase extends Database {
        /**
         * Additional $params include:
         *   - lagDetectionMethod : set to one of (Seconds_Behind_Master,pt-heartbeat).
-        *                          pt-heartbeat assumes the table is at heartbeat.heartbeat
-        *                          and uses UTC timestamps in the heartbeat.ts column.
-        *                          (https://www.percona.com/doc/percona-toolkit/2.2/pt-heartbeat.html)
+        *       pt-heartbeat assumes the table is at heartbeat.heartbeat
+        *       and uses UTC timestamps in the heartbeat.ts column.
+        *       (https://www.percona.com/doc/percona-toolkit/2.2/pt-heartbeat.html)
         *   - lagDetectionOptions : if using pt-heartbeat, this can be set to an array map to change
-        *                           the default behavior. Normally, the heartbeat row with the server
-        *                           ID of this server's master will be used. Set the "conds" field to
-        *                           override the query conditions, e.g. ['shard' => 's1'].
+        *       the default behavior. Normally, the heartbeat row with the server
+        *       ID of this server's master will be used. Set the "conds" field to
+        *       override the query conditions, e.g. ['shard' => 's1'].
+        *   - useGTIDs : use GTID methods like MASTER_GTID_WAIT() when possible.
         * @param array $params
         */
        function __construct( array $params ) {
@@ -61,6 +64,7 @@ abstract class DatabaseMysqlBase extends Database {
                $this->lagDetectionOptions = isset( $params['lagDetectionOptions'] )
                        ? $params['lagDetectionOptions']
                        : [];
+               $this->useGTIDs = !empty( $params['useGTIDs' ] );
        }
 
        /**
@@ -788,13 +792,20 @@ abstract class DatabaseMysqlBase extends Database {
                        return 0; // already reached this point for sure
                }
 
-               # Commit any open transactions
+               // Commit any open transactions
                $this->commit( __METHOD__, 'flush' );
 
-               # Call doQuery() directly, to avoid opening a transaction if DBO_TRX is set
-               $encFile = $this->addQuotes( $pos->file );
-               $encPos = intval( $pos->pos );
-               $res = $this->doQuery( "SELECT MASTER_POS_WAIT($encFile, $encPos, $timeout)" );
+               // Call doQuery() directly, to avoid opening a transaction if DBO_TRX is set
+               if ( $this->useGTIDs && $pos->gtids ) {
+                       // Wait on the GTID set (MariaDB only)
+                       $gtidArg = implode( ',', $pos->gtids );
+                       $res = $this->doQuery( "SELECT MASTER_GTID_WAIT($gtidArg, $timeout)" );
+               } else {
+                       // Wait on the binlog coordinates
+                       $encFile = $this->addQuotes( $pos->file );
+                       $encPos = intval( $pos->pos );
+                       $res = $this->doQuery( "SELECT MASTER_POS_WAIT($encFile, $encPos, $timeout)" );
+               }
 
                $row = $res ? $this->fetchRow( $res ) : false;
                if ( !$row ) {
@@ -827,15 +838,23 @@ abstract class DatabaseMysqlBase extends Database {
         * @return MySQLMasterPos|bool
         */
        function getSlavePos() {
-               $res = $this->query( 'SHOW SLAVE STATUS', 'DatabaseBase::getSlavePos' );
+               $res = $this->query( 'SHOW SLAVE STATUS', __METHOD__ );
                $row = $this->fetchObject( $res );
 
                if ( $row ) {
                        $pos = isset( $row->Exec_master_log_pos )
                                ? $row->Exec_master_log_pos
                                : $row->Exec_Master_Log_Pos;
+                       // Also fetch the last-applied GTID set (MariaDB)
+                       if ( $this->useGTIDs ) {
+                               $res = $this->query( "SHOW GLOBAL VARIABLES LIKE 'gtid_slave_pos'", __METHOD__ );
+                               $gtidRow = $this->fetchObject( $res );
+                               $gtidSet = $gtidRow ? $gtidRow->Value : '';
+                       } else {
+                               $gtidSet = '';
+                       }
 
-                       return new MySQLMasterPos( $row->Relay_Master_Log_File, $pos );
+                       return new MySQLMasterPos( $row->Relay_Master_Log_File, $pos, $gtidSet );
                } else {
                        return false;
                }
@@ -847,11 +866,20 @@ abstract class DatabaseMysqlBase extends Database {
         * @return MySQLMasterPos|bool
         */
        function getMasterPos() {
-               $res = $this->query( 'SHOW MASTER STATUS', 'DatabaseBase::getMasterPos' );
+               $res = $this->query( 'SHOW MASTER STATUS', __METHOD__ );
                $row = $this->fetchObject( $res );
 
                if ( $row ) {
-                       return new MySQLMasterPos( $row->File, $row->Position );
+                       // Also fetch the last-written GTID set (MariaDB)
+                       if ( $this->useGTIDs ) {
+                               $res = $this->query( "SHOW GLOBAL VARIABLES LIKE 'gtid_binlog_pos'", __METHOD__ );
+                               $gtidRow = $this->fetchObject( $res );
+                               $gtidSet = $gtidRow ? $gtidRow->Value : '';
+                       } else {
+                               $gtidSet = '';
+                       }
+
+                       return new MySQLMasterPos( $row->File, $row->Position, $gtidSet );
                } else {
                        return false;
                }
@@ -1443,20 +1471,43 @@ class MySQLField implements Field {
        }
 }
 
+/**
+ * DBMasterPos class for MySQL/MariaDB
+ *
+ * Note that master positions and sync logic here make some assumptions:
+ *  - Binlog-based usage assumes single-source replication and non-hierarchical replication.
+ *  - GTID-based usage allows getting/syncing with multi-source replication. It is assumed
+ *    that GTID sets are complete (e.g. include all domains on the server).
+ */
 class MySQLMasterPos implements DBMasterPos {
-       /** @var string */
+       /** @var string Binlog file */
        public $file;
-       /** @var int Position */
+       /** @var int Binglog file position */
        public $pos;
+       /** @var string[] GTID list */
+       public $gtids = [];
        /** @var float UNIX timestamp */
        public $asOfTime = 0.0;
 
-       function __construct( $file, $pos ) {
+       /**
+        * @param string $file Binlog file name
+        * @param integer $pos Binlog position
+        * @param string $gtid Comma separated GTID set [optional]
+        */
+       function __construct( $file, $pos, $gtid = '' ) {
                $this->file = $file;
                $this->pos = $pos;
+               $this->gtids = array_map( 'trim', explode( ',', $gtid ) );
                $this->asOfTime = microtime( true );
        }
 
+       /**
+        * @return string <binlog file>/<position>, e.g db1034-bin.000976/843431247
+        */
+       function __toString() {
+               return "{$this->file}/{$this->pos}";
+       }
+
        function asOfTime() {
                return $this->asOfTime;
        }
@@ -1466,10 +1517,29 @@ class MySQLMasterPos implements DBMasterPos {
                        throw new InvalidArgumentException( "Position not an instance of " . __CLASS__ );
                }
 
-               $thisPos = $this->getCoordinates();
-               $thatPos = $pos->getCoordinates();
+               // Prefer GTID comparisons, which work with multi-tier replication
+               $thisPosByDomain = $this->getGtidCoordinates();
+               $thatPosByDomain = $pos->getGtidCoordinates();
+               if ( $thisPosByDomain && $thatPosByDomain ) {
+                       $reached = true;
+                       // Check that this has positions GTE all of those in $pos for all domains in $pos
+                       foreach ( $thatPosByDomain as $domain => $thatPos ) {
+                               $thisPos = isset( $thisPosByDomain[$domain] ) ? $thisPosByDomain[$domain] : -1;
+                               $reached = $reached && ( $thatPos <= $thisPos );
+                       }
 
-               return ( $thisPos && $thatPos && $thisPos >= $thatPos );
+                       return $reached;
+               }
+
+               // Fallback to the binlog file comparisons
+               $thisBinPos = $this->getBinlogCoordinates();
+               $thatBinPos = $pos->getBinlogCoordinates();
+               if ( $thisBinPos && $thatBinPos && $thisBinPos['binlog'] === $thatBinPos['binlog'] ) {
+                       return ( $thisBinPos['pos'] >= $thatBinPos['pos'] );
+               }
+
+               // Comparing totally different binlogs does not make sense
+               return false;
        }
 
        function channelsMatch( DBMasterPos $pos ) {
@@ -1477,36 +1547,56 @@ class MySQLMasterPos implements DBMasterPos {
                        throw new InvalidArgumentException( "Position not an instance of " . __CLASS__ );
                }
 
-               $thisBinlog = $this->getBinlogName();
-               $thatBinlog = $pos->getBinlogName();
+               // Prefer GTID comparisons, which work with multi-tier replication
+               $thisPosDomains = array_keys( $this->getGtidCoordinates() );
+               $thatPosDomains = array_keys( $pos->getGtidCoordinates() );
+               if ( $thisPosDomains && $thatPosDomains ) {
+                       // Check that this has GTIDs for all domains in $pos
+                       return !array_diff( $thatPosDomains, $thisPosDomains );
+               }
 
-               return ( $thisBinlog !== false && $thisBinlog === $thatBinlog );
-       }
+               // Fallback to the binlog file comparisons
+               $thisBinPos = $this->getBinlogCoordinates();
+               $thatBinPos = $pos->getBinlogCoordinates();
 
-       function __toString() {
-               // e.g db1034-bin.000976/843431247
-               return "{$this->file}/{$this->pos}";
+               return ( $thisBinPos && $thatBinPos && $thisBinPos['binlog'] === $thatBinPos['binlog'] );
        }
 
        /**
-        * @return string|bool
+        * @note: this returns false for multi-source replication GTID sets
+        * @see https://mariadb.com/kb/en/mariadb/gtid
+        * @see https://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html
+        * @return array Map of (domain => integer position) or false
         */
-       protected function getBinlogName() {
-               $m = [];
-               if ( preg_match( '!^(.+)\.(\d+)/(\d+)$!', (string)$this, $m ) ) {
-                       return $m[1];
+       protected function getGtidCoordinates() {
+               $gtidInfos = [];
+               foreach ( $this->gtids as $gtid ) {
+                       $m = [];
+                       // MariaDB style: <domain>-<server id>-<sequence number>
+                       if ( preg_match( '!^(\d+)-\d+-(\d+)$!', $gtid, $m ) ) {
+                               $gtidInfos[(int)$m[1]] = (int)$m[2];
+                       // MySQL style: <UUID domain>:<sequence number>
+                       } elseif ( preg_match( '!^(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}):(\d+)$!', $gtid, $m ) ) {
+                               $gtidInfos[$m[1]] = (int)$m[2];
+                       } else {
+                               $gtidInfos = [];
+                               break; // unrecognized GTID
+                       }
+
                }
 
-               return false;
+               return $gtidInfos;
        }
 
        /**
-        * @return array|bool (int, int)
+        * @see http://dev.mysql.com/doc/refman/5.7/en/show-master-status.html
+        * @see http://dev.mysql.com/doc/refman/5.7/en/show-slave-status.html
+        * @return array|bool (binlog, (integer file number, integer position)) or false
         */
-       protected function getCoordinates() {
+       protected function getBinlogCoordinates() {
                $m = [];
-               if ( preg_match( '!\.(\d+)/(\d+)$!', (string)$this, $m ) ) {
-                       return [ (int)$m[1], (int)$m[2] ];
+               if ( preg_match( '!^(.+)\.(\d+)/(\d+)$!', (string)$this, $m ) ) {
+                       return [ 'binlog' => $m[1], 'pos' => [ (int)$m[2], (int)$m[3] ] ];
                }
 
                return false;
index 36772b8..c024632 100644 (file)
  * @ingroup Database
  */
 interface IDatabase {
+       /* Constants to onTransactionResolution() callbacks */
+       const TRIGGER_IDLE = 1;
+       const TRIGGER_COMMIT = 2;
+       const TRIGGER_ROLLBACK = 3;
+
        /**
         * A string describing the current software version, and possibly
         * other details in a user-friendly way. Will be listed on Special:Version, etc.
@@ -1223,6 +1228,9 @@ interface IDatabase {
         *
         * This is useful for combining cooperative locks and DB transactions.
         *
+        * The callback takes one argument:
+        * How the transaction ended (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_ROLLBACK)
+        *
         * @param callable $callback
         * @return mixed
         * @since 1.28
@@ -1242,6 +1250,9 @@ interface IDatabase {
         *
         * Updates will execute in the order they were enqueued.
         *
+        * The callback takes one argument:
+        * How the transaction ended (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_IDLE)
+        *
         * @param callable $callback
         * @since 1.20
         */
index 5b048b5..9a1d679 100644 (file)
@@ -224,6 +224,10 @@ abstract class LBFactory implements DestructibleService {
        public function commitMasterChanges( $fname = __METHOD__, array $options = [] ) {
                $limit = isset( $options['maxWriteDuration'] ) ? $options['maxWriteDuration'] : 0;
 
+               // Run pre-commit callbacks to keep them out of the COMMIT step. If one errors out here
+               // then all DB transactions can be rolled back before anything was committed yet.
+               $this->forEachLBCallMethod( 'runPreCommitCallbacks' );
+
                $this->logMultiDbTransaction();
                $this->forEachLB( function ( LoadBalancer $lb ) use ( $limit ) {
                        $lb->forEachOpenConnection( function ( IDatabase $db ) use ( $limit ) {
index d96c665..d9a7381 100644 (file)
@@ -1115,6 +1115,28 @@ class LoadBalancer {
                }
        }
 
+       /**
+        * Call runOnTransactionPreCommitCallbacks() on all DB handles
+        *
+        * This method should not be used outside of LBFactory/LoadBalancer
+        *
+        * @since 1.28
+        */
+       public function runPreCommitCallbacks() {
+               $masterIndex = $this->getWriterIndex();
+               foreach ( $this->mConns as $conns2 ) {
+                       if ( empty( $conns2[$masterIndex] ) ) {
+                               continue;
+                       }
+                       /** @var DatabaseBase $conn */
+                       foreach ( $conns2[$masterIndex] as $conn ) {
+                               if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
+                                       $conn->runOnTransactionPreCommitCallbacks();
+                               }
+                       }
+               }
+       }
+
        /**
         * @return bool Whether a master connection is already open
         * @since 1.24
index a9921b3..ccbd6b0 100644 (file)
@@ -9,26 +9,34 @@ class AtomicSectionUpdate implements DeferrableUpdate {
        private $dbw;
        /** @var string */
        private $fname;
-       /** @var Closure|callable */
+       /** @var callable */
        private $callback;
 
        /**
         * @param IDatabase $dbw
         * @param string $fname Caller name (usually __METHOD__)
         * @param callable $callback
-        * @throws InvalidArgumentException
         * @see IDatabase::doAtomicSection()
         */
-       public function __construct( IDatabase $dbw, $fname, $callback ) {
+       public function __construct( IDatabase $dbw, $fname, callable $callback ) {
                $this->dbw = $dbw;
                $this->fname = $fname;
-               if ( !is_callable( $callback ) ) {
-                       throw new InvalidArgumentException( 'Not a valid callback/closure!' );
-               }
                $this->callback = $callback;
+
+               if ( $this->dbw->trxLevel() ) {
+                       $this->dbw->onTransactionResolution( [ $this, 'cancelOnRollback' ] );
+               }
        }
 
        public function doUpdate() {
-               $this->dbw->doAtomicSection( $this->fname, $this->callback );
+               if ( $this->callback ) {
+                       $this->dbw->doAtomicSection( $this->fname, $this->callback );
+               }
+       }
+
+       public function cancelOnRollback( $trigger ) {
+               if ( $trigger === IDatabase::TRIGGER_ROLLBACK ) {
+                       $this->callback = null;
+               }
        }
 }
diff --git a/includes/deferred/AutoCommitUpdate.php b/includes/deferred/AutoCommitUpdate.php
new file mode 100644 (file)
index 0000000..ddf2bb8
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * Deferrable Update for closure/callback updates that should use auto-commit mode
+ * @since 1.28
+ */
+class AutoCommitUpdate implements DeferrableUpdate {
+       /** @var IDatabase */
+       private $dbw;
+       /** @var string */
+       private $fname;
+       /** @var callable */
+       private $callback;
+
+       /**
+        * @param IDatabase $dbw
+        * @param string $fname Caller name (usually __METHOD__)
+        * @param callable $callback Callback that takes (IDatabase, method name string)
+        */
+       public function __construct( IDatabase $dbw, $fname, callable $callback ) {
+               $this->dbw = $dbw;
+               $this->fname = $fname;
+               $this->callback = $callback;
+
+               if ( $this->dbw->trxLevel() ) {
+                       $this->dbw->onTransactionResolution( [ $this, 'cancelOnRollback' ] );
+               }
+       }
+
+       public function doUpdate() {
+               if ( !$this->callback ) {
+                       return;
+               }
+
+               $autoTrx = $this->dbw->getFlag( DBO_TRX );
+               $this->dbw->clearFlag( DBO_TRX );
+               try {
+                       /** @var Exception $e */
+                       $e = null;
+                       call_user_func_array( $this->callback, [ $this->dbw, $this->fname ] );
+               } catch ( Exception $e ) {
+               }
+               if ( $autoTrx ) {
+                       $this->dbw->setFlag( DBO_TRX );
+               }
+               if ( $e ) {
+                       throw $e;
+               }
+       }
+
+       public function cancelOnRollback( $trigger ) {
+               if ( $trigger === IDatabase::TRIGGER_ROLLBACK ) {
+                       $this->callback = null;
+               }
+       }
+}
index a7c39ca..0009781 100644 (file)
@@ -61,6 +61,8 @@ class LinksDeletionUpdate extends SqlDataUpdate implements EnqueueableDataUpdate
                // This handles the case when updates have to batched into several COMMITs.
                $scopedLock = LinksUpdate::acquirePageLock( $this->mDb, $id );
 
+               $title = $this->page->getTitle();
+
                // Delete restrictions for it
                $this->mDb->delete( 'page_restrictions', [ 'pr_page' => $id ], __METHOD__ );
 
@@ -80,6 +82,20 @@ class LinksDeletionUpdate extends SqlDataUpdate implements EnqueueableDataUpdate
                        }
                }
 
+               // Refresh the category table entry if it seems to have no pages. Check
+               // master for the most up-to-date cat_pages count.
+               if ( $title->getNamespace() === NS_CATEGORY ) {
+                       $row = $this->mDb->selectRow(
+                               'category',
+                               [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
+                               [ 'cat_title' => $title->getDBkey(), 'cat_pages <= 0' ],
+                               __METHOD__
+                       );
+                       if ( $row ) {
+                               $cat = Category::newFromRow( $row, $title )->refreshCounts();
+                       }
+               }
+
                // If using cascading deletes, we can skip some explicit deletes
                if ( !$this->mDb->cascadingDeletes() ) {
                        // Delete outgoing links
@@ -132,7 +148,6 @@ class LinksDeletionUpdate extends SqlDataUpdate implements EnqueueableDataUpdate
 
                // If using cleanup triggers, we can skip some manual deletes
                if ( !$this->mDb->cleanupTriggers() ) {
-                       $title = $this->page->getTitle();
                        // Find recentchanges entries to clean up...
                        $rcIdsForTitle = $this->mDb->selectFieldValues(
                                'recentchanges',
@@ -164,10 +179,8 @@ class LinksDeletionUpdate extends SqlDataUpdate implements EnqueueableDataUpdate
                        }
                }
 
-               $this->mDb->onTransactionIdle( function() use ( &$scopedLock ) {
-                       // Release the lock *after* the final COMMIT for correctness
-                       ScopedCallback::consume( $scopedLock );
-               } );
+               // Commit and release the lock
+               ScopedCallback::consume( $scopedLock );
        }
 
        private function batchDeleteByPK( $table, array $conds, array $pk, $bSize ) {
index d4a61fa..22944eb 100644 (file)
@@ -168,18 +168,16 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
         *
         * @param IDatabase $dbw
         * @param integer $pageId
-        * @return ScopedCallback|null Returns null on failure
+        * @param string $why One of (job, atomicity)
+        * @return ScopedCallback
         * @throws RuntimeException
         * @since 1.27
         */
-       public static function acquirePageLock( IDatabase $dbw, $pageId ) {
-               $scopedLock = $dbw->getScopedLockAndFlush(
-                       "LinksUpdate:pageid:$pageId",
-                       __METHOD__,
-                       15
-               );
+       public static function acquirePageLock( IDatabase $dbw, $pageId, $why = 'atomicity' ) {
+               $key = "LinksUpdate:$why:pageid:$pageId";
+               $scopedLock = $dbw->getScopedLockAndFlush( $key, __METHOD__, 15 );
                if ( !$scopedLock ) {
-                       throw new RuntimeException( "Could not acquire lock on page #$pageId." );
+                       throw new RuntimeException( "Could not acquire lock '$key'." );
                }
 
                return $scopedLock;
index 5a62185..b8e2726 100644 (file)
@@ -74,7 +74,7 @@ class SiteStatsUpdate implements DeferrableUpdate {
                        $this->doUpdatePendingDeltas();
                } else {
                        // Need a separate transaction because this a global lock
-                       wfGetDB( DB_MASTER )->onTransactionIdle( [ $this, 'tryDBUpdateInternal' ] );
+                       DeferredUpdates::addCallableUpdate( [ $this, 'tryDBUpdateInternal' ] );
                }
        }
 
index af5fbf3..bd7629a 100644 (file)
  * @ingroup DifferenceEngine
  */
 
-/**
- * Constant to indicate diff cache compatibility.
- * Bump this when changing the diff formatting in a way that
- * fixes important bugs or such to force cached diff views to
- * clear.
- */
+// Deprecated, use class constant instead
 define( 'MW_DIFF_VERSION', '1.11a' );
 
 /**
@@ -34,6 +29,13 @@ define( 'MW_DIFF_VERSION', '1.11a' );
  * @ingroup DifferenceEngine
  */
 class DifferenceEngine extends ContextSource {
+       /**
+        * Constant to indicate diff cache compatibility.
+        * Bump this when changing the diff formatting in a way that
+        * fixes important bugs or such to force cached diff views to
+        * clear.
+        */
+       const DIFF_VERSION = MW_DIFF_VERSION;
 
        /** @var int */
        public $mOldid;
@@ -777,7 +779,7 @@ class DifferenceEngine extends ContextSource {
                        throw new MWException( 'mOldid and mNewid must be set to get diff cache key.' );
                }
 
-               return wfMemcKey( 'diff', 'version', MW_DIFF_VERSION,
+               return wfMemcKey( 'diff', 'version', self::MW_DIFF_VERSION,
                        'oldid', $this->mOldid, 'newid', $this->mNewid );
        }
 
index e4ff5f3..7d8b244 100644 (file)
@@ -488,7 +488,11 @@ TXT;
                return "[$id] $url   $type from line $line of $file: $message";
        }
 
-       public static function getPublicLogMessage( Exception $e ) {
+       /**
+        * @param Exception|Throwable $e
+        * @return string
+        */
+       public static function getPublicLogMessage( $e ) {
                $reqId = WebRequest::getRequestId();
                $type = get_class( $e );
                return '[' . $reqId . '] '
diff --git a/includes/export/DumpStringOutput.php b/includes/export/DumpStringOutput.php
new file mode 100644 (file)
index 0000000..837a62d
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Stream outputter that buffers and returns data as a string.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * @ingroup Dump
+ * @since 1.28
+ */
+class DumpStringOutput extends DumpOutput {
+       private $output = '';
+
+       /**
+        * @param string $string
+        */
+       function write( $string ) {
+               $this->output .= $string;
+       }
+
+       /**
+        * Get the string containing the output.
+        *
+        * @return string
+        */
+       public function __toString() {
+               return $this->output;
+       }
+}
index 03974f7..10183f4 100644 (file)
@@ -1005,15 +1005,21 @@ abstract class FileBackend {
 
        /**
         * Stream the file at a storage path in the backend.
+        *
         * If the file does not exists, an HTTP 404 error will be given.
         * Appropriate HTTP headers (Status, Content-Type, Content-Length)
         * will be sent if streaming began, while none will be sent otherwise.
         * Implementations should flush the output buffer before sending data.
         *
         * @param array $params Parameters include:
-        *   - src     : source storage path
-        *   - headers : list of additional HTTP headers to send on success
-        *   - latest  : use the latest available data
+        *   - src      : source storage path
+        *   - headers  : list of additional HTTP headers to send if the file exists
+        *   - options  : HTTP request header map with lower case keys (since 1.28). Supports:
+        *                range             : format is "bytes=(\d*-\d*)"
+        *                if-modified-since : format is an HTTP date
+        *   - headless : only include the body (and headers from "headers") (since 1.28)
+        *   - latest   : use the latest available data
+        *   - allowOB  : preserve any output buffers (since 1.28)
         * @return Status
         */
        abstract public function streamFile( array $params );
index 4d9587e..a29119c 100644 (file)
@@ -844,30 +844,19 @@ abstract class FileBackendStore extends FileBackend {
                $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
                $status = Status::newGood();
 
-               $info = $this->getFileStat( $params );
-               if ( !$info ) { // let StreamFile handle the 404
-                       $status->fatal( 'backend-fail-notexists', $params['src'] );
-               }
-
-               // Set output buffer and HTTP headers for stream
-               $extraHeaders = isset( $params['headers'] ) ? $params['headers'] : [];
-               $res = StreamFile::prepareForStream( $params['src'], $info, $extraHeaders );
-               if ( $res == StreamFile::NOT_MODIFIED ) {
-                       // do nothing; client cache is up to date
-               } elseif ( $res == StreamFile::READY_STREAM ) {
-                       $status = $this->doStreamFile( $params );
-                       if ( !$status->isOK() ) {
-                               // Per bug 41113, nasty things can happen if bad cache entries get
-                               // stuck in cache. It's also possible that this error can come up
-                               // with simple race conditions. Clear out the stat cache to be safe.
-                               $this->clearCache( [ $params['src'] ] );
-                               $this->deleteFileCache( $params['src'] );
-                               trigger_error( "Bad stat cache or race condition for file {$params['src']}." );
-                       }
-               } else {
+               // Always set some fields for subclass convenience
+               $params['options'] = isset( $params['options'] ) ? $params['options'] : [];
+               $params['headers'] = isset( $params['headers'] ) ? $params['headers'] : [];
+
+               // Don't stream it out as text/html if there was a PHP error
+               if ( ( empty( $params['headless'] ) || $params['headers'] ) && headers_sent() ) {
+                       print "Headers already sent, terminating.\n";
                        $status->fatal( 'backend-fail-stream', $params['src'] );
+                       return $status;
                }
 
+               $status->merge( $this->doStreamFile( $params ) );
+
                return $status;
        }
 
@@ -879,10 +868,21 @@ abstract class FileBackendStore extends FileBackend {
        protected function doStreamFile( array $params ) {
                $status = Status::newGood();
 
+               $flags = 0;
+               $flags |= !empty( $params['headless'] ) ? StreamFile::STREAM_HEADLESS : 0;
+               $flags |= !empty( $params['allowOB'] ) ? StreamFile::STREAM_ALLOW_OB : 0;
+
                $fsFile = $this->getLocalReference( $params );
-               if ( !$fsFile ) {
-                       $status->fatal( 'backend-fail-stream', $params['src'] );
-               } elseif ( !readfile( $fsFile->getPath() ) ) {
+
+               if ( $fsFile ) {
+                       $res = StreamFile::stream( $fsFile->getPath(),
+                               $params['headers'], true, $params['options'], $flags );
+               } else {
+                       $res = false;
+                       StreamFile::send404Message( $params['src'], $flags );
+               }
+
+               if ( !$res ) {
                        $status->fatal( 'backend-fail-stream', $params['src'] );
                }
 
index 6e32c62..e2c1ede 100644 (file)
@@ -183,21 +183,6 @@ class MemoryFileBackend extends FileBackendStore {
                return $tmpFiles;
        }
 
-       protected function doStreamFile( array $params ) {
-               $status = Status::newGood();
-
-               $src = $this->resolveHashKey( $params['src'] );
-               if ( $src === null || !isset( $this->files[$src] ) ) {
-                       $status->fatal( 'backend-fail-stream', $params['src'] );
-
-                       return $status;
-               }
-
-               print $this->files[$src]['data'];
-
-               return $status;
-       }
-
        protected function doDirectoryExists( $container, $dir, array $params ) {
                $prefix = rtrim( "$container/$dir", '/' ) . '/';
                foreach ( $this->files as $path => $data ) {
index 0f7e4b5..2adf934 100644 (file)
@@ -1045,32 +1045,62 @@ class SwiftFileBackend extends FileBackendStore {
        protected function doStreamFile( array $params ) {
                $status = Status::newGood();
 
+               $flags = !empty( $params['headless'] ) ? StreamFile::STREAM_HEADLESS : 0;
+
                list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
                if ( $srcRel === null ) {
+                       StreamFile::send404Message( $params['src'], $flags );
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
+                       return $status;
                }
 
                $auth = $this->getAuthentication();
                if ( !$auth || !is_array( $this->getContainerStat( $srcCont ) ) ) {
+                       StreamFile::send404Message( $params['src'], $flags );
                        $status->fatal( 'backend-fail-stream', $params['src'] );
 
                        return $status;
                }
 
-               $handle = fopen( 'php://output', 'wb' );
+               // If "headers" is set, we only want to send them if the file is there.
+               // Do not bother checking if the file exists if headers are not set though.
+               if ( $params['headers'] && !$this->fileExists( $params ) ) {
+                       StreamFile::send404Message( $params['src'], $flags );
+                       $status->fatal( 'backend-fail-stream', $params['src'] );
 
+                       return $status;
+               }
+
+               // Send the requested additional headers
+               foreach ( $params['headers'] as $header ) {
+                       header( $header ); // aways send
+               }
+
+               if ( empty( $params['allowOB'] ) ) {
+                       // Cancel output buffering and gzipping if set
+                       wfResetOutputBuffers();
+               }
+
+               $handle = fopen( 'php://output', 'wb' );
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( [
                        'method' => 'GET',
                        'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
                        'headers' => $this->authTokenHeaders( $auth )
-                               + $this->headersFromParams( $params ),
+                               + $this->headersFromParams( $params ) + $params['options'],
                        'stream' => $handle,
+                       'flags'  => [ 'relayResponseHeaders' => empty( $params['headless'] ) ]
                ] );
 
                if ( $rcode >= 200 && $rcode <= 299 ) {
                        // good
                } elseif ( $rcode === 404 ) {
                        $status->fatal( 'backend-fail-stream', $params['src'] );
+                       // Per bug 41113, nasty things can happen if bad cache entries get
+                       // stuck in cache. It's also possible that this error can come up
+                       // with simple race conditions. Clear out the stat cache to be safe.
+                       $this->clearCache( [ $params['src'] ] );
+                       $this->deleteFileCache( $params['src'] );
                } else {
                        $this->onError( $status, __METHOD__, $params, $rerr, $rcode, $rdesc );
                }
index d7559d0..4ab913d 100644 (file)
@@ -1585,12 +1585,13 @@ class FileRepo {
         *
         * @param string $virtualUrl
         * @param array $headers Additional HTTP headers to send on success
+        * @param array $optHeaders HTTP request headers (if-modified-since, range, ...)
         * @return Status
         * @since 1.27
         */
-       public function streamFileWithStatus( $virtualUrl, $headers = [] ) {
+       public function streamFileWithStatus( $virtualUrl, $headers = [], $optHeaders = [] ) {
                $path = $this->resolveToStoragePath( $virtualUrl );
-               $params = [ 'src' => $path, 'headers' => $headers ];
+               $params = [ 'src' => $path, 'headers' => $headers, 'options' => $optHeaders ];
 
                return $this->backend->streamFile( $params );
        }
index 5d63645..e35af75 100644 (file)
@@ -129,6 +129,8 @@ class LocalFile extends File {
        // @note: higher than IDBAccessObject constants
        const LOAD_ALL = 16; // integer; load all the lazy fields too (like metadata)
 
+       const ATOMIC_SECTION_LOCK = 'LocalFile::lockingTransaction';
+
        /**
         * Create a LocalFile from a title
         * Do not call this except from inside a repo class.
@@ -1635,16 +1637,20 @@ class LocalFile extends File {
                // Purge the source and target files...
                $oldTitleFile = wfLocalFile( $this->title );
                $newTitleFile = wfLocalFile( $target );
-               // Hack: the lock()/unlock() pair is nested in a transaction so the locking is not
-               // tied to BEGIN/COMMIT. To avoid slow purges in the transaction, move them outside.
-               $this->getRepo()->getMasterDB()->onTransactionIdle(
-                       function () use ( $oldTitleFile, $newTitleFile, $archiveNames ) {
-                               $oldTitleFile->purgeEverything();
-                               foreach ( $archiveNames as $archiveName ) {
-                                       $oldTitleFile->purgeOldThumbnails( $archiveName );
+               // To avoid slow purges in the transaction, move them outside...
+               DeferredUpdates::addUpdate(
+                       new AutoCommitUpdate(
+                               $this->getRepo()->getMasterDB(),
+                               __METHOD__,
+                               function () use ( $oldTitleFile, $newTitleFile, $archiveNames ) {
+                                       $oldTitleFile->purgeEverything();
+                                       foreach ( $archiveNames as $archiveName ) {
+                                               $oldTitleFile->purgeOldThumbnails( $archiveName );
+                                       }
+                                       $newTitleFile->purgeEverything();
                                }
-                               $newTitleFile->purgeEverything();
-                       }
+                       ),
+                       DeferredUpdates::PRESEND
                );
 
                if ( $status->isOK() ) {
@@ -1680,7 +1686,7 @@ class LocalFile extends File {
 
                $this->lock(); // begin
                $batch->addCurrent();
-               # Get old version relative paths
+               // Get old version relative paths
                $archiveNames = $batch->addOlds();
                $status = $batch->execute();
                $this->unlock(); // done
@@ -1689,16 +1695,19 @@ class LocalFile extends File {
                        DeferredUpdates::addUpdate( SiteStatsUpdate::factory( [ 'images' => -1 ] ) );
                }
 
-               // Hack: the lock()/unlock() pair is nested in a transaction so the locking is not
-               // tied to BEGIN/COMMIT. To avoid slow purges in the transaction, move them outside.
-               $that = $this;
-               $this->getRepo()->getMasterDB()->onTransactionIdle(
-                       function () use ( $that, $archiveNames ) {
-                               $that->purgeEverything();
-                               foreach ( $archiveNames as $archiveName ) {
-                                       $that->purgeOldThumbnails( $archiveName );
+               // To avoid slow purges in the transaction, move them outside...
+               DeferredUpdates::addUpdate(
+                       new AutoCommitUpdate(
+                               $this->getRepo()->getMasterDB(),
+                               __METHOD__,
+                               function () use ( $archiveNames ) {
+                                       $this->purgeEverything();
+                                       foreach ( $archiveNames as $archiveName ) {
+                                               $this->purgeOldThumbnails( $archiveName );
+                                       }
                                }
-                       }
+                       ),
+                       DeferredUpdates::PRESEND
                );
 
                // Purge the CDN
@@ -1905,19 +1914,19 @@ class LocalFile extends File {
        }
 
        /**
-        * Start a transaction and lock the image for update
-        * Increments a reference counter if the lock is already held
+        * Start an atomic DB section and lock the image for update
+        * or increments a reference counter if the lock is already held
+        *
         * @throws LocalFileLockError Throws an error if the lock was not acquired
         * @return bool Whether the file lock owns/spawned the DB transaction
         */
        function lock() {
                if ( !$this->locked ) {
                        $logger = LoggerFactory::getInstance( 'LocalFile' );
+
                        $dbw = $this->repo->getMasterDB();
-                       if ( !$dbw->trxLevel() ) {
-                               $dbw->begin( __METHOD__ );
-                               $this->lockedOwnTrx = true;
-                       }
+                       $makesTransaction = !$dbw->trxLevel();
+                       $dbw->startAtomic( self::ATOMIC_SECTION_LOCK );
                        // Bug 54736: use simple lock to handle when the file does not exist.
                        // SELECT FOR UPDATE prevents changes, not other SELECTs with FOR UPDATE.
                        // Also, that would cause contention on INSERT of similarly named rows.
@@ -1925,9 +1934,7 @@ class LocalFile extends File {
                        $lockPaths = [ $this->getPath() ]; // represents all versions of the file
                        $status = $backend->lockFiles( $lockPaths, LockManager::LOCK_EX, 10 );
                        if ( !$status->isGood() ) {
-                               if ( $this->lockedOwnTrx ) {
-                                       $dbw->rollback( __METHOD__ );
-                               }
+                               $dbw->endAtomic( self::ATOMIC_SECTION_LOCK );
                                $logger->warning( "Failed to lock '{file}'", [ 'file' => $this->name ] );
 
                                throw new LocalFileLockError( $status );
@@ -1940,6 +1947,8 @@ class LocalFile extends File {
                                        $logger->error( "Failed to unlock '{file}'", [ 'file' => $this->name ] );
                                }
                        } );
+                       // Callers might care if the SELECT snapshot is safely fresh
+                       $this->lockedOwnTrx = $makesTransaction;
                }
 
                $this->locked++;
@@ -1948,15 +1957,17 @@ class LocalFile extends File {
        }
 
        /**
-        * Decrement the lock reference count. If the reference count is reduced to zero, commits
-        * the transaction and thereby releases the image lock.
+        * Decrement the lock reference count and end the atomic section if it reaches zero
+        *
+        * The commit and loc release will happen when no atomic sections are active, which
+        * may happen immediately or at some point after calling this
         */
        function unlock() {
                if ( $this->locked ) {
                        --$this->locked;
-                       if ( !$this->locked && $this->lockedOwnTrx ) {
+                       if ( !$this->locked ) {
                                $dbw = $this->repo->getMasterDB();
-                               $dbw->commit( __METHOD__ );
+                               $dbw->endAtomic( self::ATOMIC_SECTION_LOCK );
                                $this->lockedOwnTrx = false;
                        }
                }
@@ -2282,13 +2293,6 @@ class LocalFileDeleteBatch {
                        }
                }
 
-               // Lock the filearchive rows so that the files don't get deleted by a cleanup operation
-               // We acquire this lock by running the inserts now, before the file operations.
-               // This potentially has poor lock contention characteristics -- an alternative
-               // scheme would be to insert stub filearchive entries with no fa_name and commit
-               // them in a separate transaction, then run the file ops, then update the fa_name fields.
-               $this->doDBInserts();
-
                if ( !$repo->hasSha1Storage() ) {
                        // Removes non-existent file from the batch, so we don't get errors.
                        // This also handles files in the 'deleted' zone deleted via revision deletion.
@@ -2301,21 +2305,20 @@ class LocalFileDeleteBatch {
 
                        // Execute the file deletion batch
                        $status = $this->file->repo->deleteBatch( $this->deletionBatch );
-
                        if ( !$status->isGood() ) {
                                $this->status->merge( $status );
                        }
                }
 
                if ( !$this->status->isOK() ) {
-                       // Critical file deletion error
-                       // Roll back inserts, release lock and abort
-                       // TODO: delete the defunct filearchive rows if we are using a non-transactional DB
-                       $this->file->unlockAndRollback();
+                       // Critical file deletion error; abort
+                       $this->file->unlock();
 
                        return $this->status;
                }
 
+               // Copy the image/oldimage rows to filearchive
+               $this->doDBInserts();
                // Delete image/oldimage rows
                $this->doDBDeletes();
 
index 73f4b19..6884f65 100644 (file)
@@ -113,7 +113,7 @@ abstract class ImageGalleryBase extends ContextSource {
                                'packed' => 'PackedImageGallery',
                                'packed-hover' => 'PackedHoverImageGallery',
                                'packed-overlay' => 'PackedOverlayImageGallery',
-                               'slider' => 'SliderImageGallery',
+                               'slideshow' => 'SlideshowImageGallery',
                        ];
                        // Allow extensions to make a new gallery format.
                        Hooks::run( 'GalleryGetModes', [ &self::$modeMapping ] );
diff --git a/includes/gallery/SliderImageGallery.php b/includes/gallery/SliderImageGallery.php
deleted file mode 100644 (file)
index 67be9ce..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/**
- * Slider gallery shows one image at a time with controls to move around.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-class SliderImageGallery extends TraditionalImageGallery {
-       function __construct( $mode = 'traditional', IContextSource $context = null ) {
-               parent::__construct( $mode, $context );
-               // Does not support per row option.
-               $this->mPerRow = 0;
-       }
-
-       /**
-        * Add javascript adds interface elements
-        * @return array
-        */
-       protected function getModules() {
-               return [ 'mediawiki.page.gallery.slider' ];
-       }
-}
diff --git a/includes/gallery/SlideshowImageGallery.php b/includes/gallery/SlideshowImageGallery.php
new file mode 100644 (file)
index 0000000..3f0c932
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+/**
+ * A slideshow gallery shows one image at a time with controls to move around.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class SlideshowImageGallery extends TraditionalImageGallery {
+       function __construct( $mode = 'traditional', IContextSource $context = null ) {
+               parent::__construct( $mode, $context );
+               // Does not support per row option.
+               $this->mPerRow = 0;
+       }
+
+       /**
+        * Add javascript adds interface elements
+        * @return array
+        */
+       protected function getModules() {
+               return [ 'mediawiki.page.gallery.slideshow' ];
+       }
+}
index 2fb2281..f6527b8 100644 (file)
@@ -189,8 +189,16 @@ class TraditionalImageGallery extends ImageGalleryBase {
                                // Preloaded into LinkCache above
                                Linker::linkKnown(
                                        $nt,
-                                       htmlspecialchars( $lang->truncate( $nt->getText(), $this->mCaptionLength ) )
-                               ) . "<br />\n" :
+                                       htmlspecialchars(
+                                               $this->mCaptionLength !== true ?
+                                                       $lang->truncate( $nt->getText(), $this->mCaptionLength ) :
+                                                       $nt->getText()
+                                       ),
+                                       [
+                                               'class' => 'galleryfilename' .
+                                                       ( $this->mCaptionLength === true ? ' galleryfilename-truncate' : '' )
+                                       ]
+                               ) . "\n" :
                                '';
 
                        $galleryText = $textlink . $text . $fileSize;
index 4a6b804..a553839 100644 (file)
@@ -118,9 +118,9 @@ class HTMLCheckField extends HTMLFormField {
 
                // GetCheck won't work like we want for checks.
                // Fetch the value in either one of the two following case:
-               // - we have a valid token (form got posted or GET forged by the user)
+               // - we have a valid submit attempt (form was just submitted, or a GET URL forged by the user)
                // - checkbox name has a value (false or true), ie is not null
-               if ( $request->getCheck( 'wpEditToken' ) || $request->getVal( $this->mName ) !== null ) {
+               if ( $this->isSubmitAttempt( $request ) || $request->getVal( $this->mName ) !== null ) {
                        return $invert
                                ? !$request->getBool( $this->mName )
                                : $request->getBool( $this->mName );
index 9f67233..b324fb6 100644 (file)
@@ -225,22 +225,13 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
         * @return array
         */
        function loadDataFromRequest( $request ) {
-               if ( $this->mParent->getMethod() == 'post' ) {
-                       if ( $request->wasPosted() ) {
-                               // Checkboxes are not added to the request arrays if they're not checked,
-                               // so it's perfectly possible for there not to be an entry at all
-                               return $request->getArray( $this->mName, [] );
-                       } else {
-                               // That's ok, the user has not yet submitted the form, so show the defaults
-                               return $this->getDefault();
-                       }
-               } else {
-                       // This is the impossible case: if we look at $_GET and see no data for our
-                       // field, is it because the user has not yet submitted the form, or that they
-                       // have submitted it with all the options unchecked. We will have to assume the
-                       // latter, which basically means that you can't specify 'positive' defaults
-                       // for GET forms.
+               if ( $this->isSubmitAttempt( $request ) ) {
+                       // Checkboxes are just not added to the request arrays if they're not checked,
+                       // so it's perfectly possible for there not to be an entry at all
                        return $request->getArray( $this->mName, [] );
+               } else {
+                       // That's ok, the user has not yet submitted the form, so show the defaults
+                       return $this->getDefault();
                }
        }
 
index 8ac4cf2..2b7417e 100644 (file)
@@ -190,6 +190,7 @@ class HTMLForm extends ContextSource {
        protected $mSubmitText;
        protected $mSubmitTooltip;
 
+       protected $mFormIdentifier;
        protected $mTitle;
        protected $mMethod = 'post';
        protected $mWasSubmitted = false;
@@ -480,7 +481,14 @@ class HTMLForm extends ContextSource {
                }
 
                # Load data from the request.
-               $this->loadData();
+               if (
+                       $this->mFormIdentifier === null ||
+                       $this->getRequest()->getVal( 'wpFormIdentifier' ) === $this->mFormIdentifier
+               ) {
+                       $this->loadData();
+               } else {
+                       $this->mFieldData = [];
+               }
 
                return $this;
        }
@@ -492,22 +500,29 @@ class HTMLForm extends ContextSource {
        public function tryAuthorizedSubmit() {
                $result = false;
 
-               $submit = false;
+               $identOkay = false;
+               if ( $this->mFormIdentifier === null ) {
+                       $identOkay = true;
+               } else {
+                       $identOkay = $this->getRequest()->getVal( 'wpFormIdentifier' ) === $this->mFormIdentifier;
+               }
+
+               $tokenOkay = false;
                if ( $this->getMethod() !== 'post' ) {
-                       $submit = true; // no session check needed
+                       $tokenOkay = true; // no session check needed
                } elseif ( $this->getRequest()->wasPosted() ) {
                        $editToken = $this->getRequest()->getVal( 'wpEditToken' );
                        if ( $this->getUser()->isLoggedIn() || $editToken !== null ) {
                                // Session tokens for logged-out users have no security value.
                                // However, if the user gave one, check it in order to give a nice
                                // "session expired" error instead of "permission denied" or such.
-                               $submit = $this->getUser()->matchEditToken( $editToken, $this->mTokenSalt );
+                               $tokenOkay = $this->getUser()->matchEditToken( $editToken, $this->mTokenSalt );
                        } else {
-                               $submit = true;
+                               $tokenOkay = true;
                        }
                }
 
-               if ( $submit ) {
+               if ( $tokenOkay && $identOkay ) {
                        $this->mWasSubmitted = true;
                        $result = $this->trySubmit();
                }
@@ -1042,6 +1057,12 @@ class HTMLForm extends ContextSource {
         */
        public function getHiddenFields() {
                $html = '';
+               if ( $this->mFormIdentifier !== null ) {
+                       $html .= Html::hidden(
+                               'wpFormIdentifier',
+                               $this->mFormIdentifier
+                       ) . "\n";
+               }
                if ( $this->getMethod() === 'post' ) {
                        $html .= Html::hidden(
                                'wpEditToken',
@@ -1327,6 +1348,27 @@ class HTMLForm extends ContextSource {
                return $this;
        }
 
+       /**
+        * Set an internal identifier for this form. It will be submitted as a hidden form field, allowing
+        * HTMLForm to determine whether the form was submitted (or merely viewed). Setting this serves
+        * two purposes:
+        *
+        * - If you use two or more forms on one page, it allows HTMLForm to identify which of the forms
+        *   was submitted, and not attempt to validate the other ones.
+        * - If you use checkbox or multiselect fields inside a form using the GET method, it allows
+        *   HTMLForm to distinguish between the initial page view and a form submission with all
+        *   checkboxes or select options unchecked.
+        *
+        * @since 1.28
+        * @param string $ident
+        * @return $this
+        */
+       public function setFormIdentifier( $ident ) {
+               $this->mFormIdentifier = $ident;
+
+               return $this;
+       }
+
        /**
         * Stop a default submit button being shown for this form. This implies that an
         * alternate submit method must be provided manually.
index 9f5e728..7cb497d 100644 (file)
@@ -349,6 +349,20 @@ abstract class HTMLFormField {
                $this->mShowEmptyLabels = $show;
        }
 
+       /**
+        * Can we assume that the request is an attempt to submit a HTMLForm, as opposed to an attempt to
+        * just view it? This can't normally be distinguished for e.g. checkboxes.
+        *
+        * Returns true if the request has a field for a CSRF token (wpEditToken) or a form identifier
+        * (wpFormIdentifier).
+        *
+        * @param WebRequest $request
+        * @return boolean
+        */
+       protected function isSubmitAttempt( WebRequest $request ) {
+               return $request->getCheck( 'wpEditToken' ) || $request->getCheck( 'wpFormIdentifier' );
+       }
+
        /**
         * Get the value that this input has been set to from a posted form,
         * or the input's default value if it has not been set.
index 23125bd..a231b2f 100644 (file)
@@ -123,23 +123,13 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
         * @return string
         */
        function loadDataFromRequest( $request ) {
-               if ( $this->mParent->getMethod() == 'post' ) {
-                       if ( $request->wasPosted() ) {
-                               # Checkboxes are just not added to the request arrays if they're not checked,
-                               # so it's perfectly possible for there not to be an entry at all
-                               return $request->getArray( $this->mName, [] );
-                       } else {
-                               # That's ok, the user has not yet submitted the form, so show the defaults
-                               return $this->getDefault();
-                       }
-               } else {
-                       # This is the impossible case: if we look at $_GET and see no data for our
-                       # field, is it because the user has not yet submitted the form, or that they
-                       # have submitted it with all the options unchecked? We will have to assume the
-                       # latter, which basically means that you can't specify 'positive' defaults
-                       # for GET forms.
-                       # @todo FIXME...
+               if ( $this->isSubmitAttempt( $request ) ) {
+                       // Checkboxes are just not added to the request arrays if they're not checked,
+                       // so it's perfectly possible for there not to be an entry at all
                        return $request->getArray( $this->mName, [] );
+               } else {
+                       // That's ok, the user has not yet submitted the form, so show the defaults
+                       return $this->getDefault();
                }
        }
 
index e57e170..86b2f3b 100644 (file)
@@ -75,6 +75,7 @@ abstract class DatabaseUpdater {
                PopulateFilearchiveSha1::class,
                PopulateBacklinkNamespace::class,
                FixDefaultJsonContentPages::class,
+               CleanupEmptyCategories::class,
        ];
 
        /**
index 4d5aa7a..5e3758d 100644 (file)
@@ -180,6 +180,7 @@ abstract class Installer {
                'wgUseInstantCommons',
                'wgUpgradeKey',
                'wgDefaultSkin',
+               'wgPingback',
        ];
 
        /**
index ced7b93..1d7c7f2 100644 (file)
@@ -64,7 +64,7 @@ class LocalSettingsGenerator {
                                'wgRightsText', '_MainCacheType', 'wgEnableUploads',
                                '_MemCachedServers', 'wgDBserver', 'wgDBuser',
                                'wgDBpassword', 'wgUseInstantCommons', 'wgUpgradeKey', 'wgDefaultSkin',
-                               'wgMetaNamespace', 'wgLogo', 'wgAuthenticationTokenVersion',
+                               'wgMetaNamespace', 'wgLogo', 'wgAuthenticationTokenVersion', 'wgPingback',
                        ],
                        $db->getGlobalNames()
                );
@@ -72,7 +72,8 @@ class LocalSettingsGenerator {
                $unescaped = [ 'wgRightsIcon', 'wgLogo' ];
                $boolItems = [
                        'wgEnableEmail', 'wgEnableUserEmail', 'wgEnotifUserTalk',
-                       'wgEnotifWatchlist', 'wgEmailAuthentication', 'wgEnableUploads', 'wgUseInstantCommons'
+                       'wgEnotifWatchlist', 'wgEmailAuthentication', 'wgEnableUploads', 'wgUseInstantCommons',
+                       'wgPingback',
                ];
 
                foreach ( $confItems as $c ) {
@@ -372,6 +373,11 @@ ${serverSetting}
 # InstantCommons allows wiki to use images from https://commons.wikimedia.org
 \$wgUseInstantCommons = {$this->values['wgUseInstantCommons']};
 
+# Periodically send a pingback to https://www.mediawiki.org/ with basic data
+# about this MediaWiki instance. The Wikimedia Foundation shares this data
+# with MediaWiki developers to help guide future development efforts.
+\$wgPingback = {$this->values['wgPingback']};
+
 ## If you use ImageMagick (or any other shell command) on a
 ## Linux server, this will need to be set to the name of an
 ## available UTF-8 locale
index dcd30cf..2345d89 100644 (file)
@@ -100,6 +100,12 @@ class WebInstallerName extends WebInstallerPage {
                                'label' => 'config-subscribe',
                                'help' => $this->parent->getHelpBox( 'config-subscribe-help' )
                        ] ) .
+                       $this->parent->getCheckBox( [
+                               'var' => 'wgPingback',
+                               'label' => 'config-pingback',
+                               'help' => $this->parent->getHelpBox( 'config-pingback-help' ),
+                               'value' => true,
+                       ] ) .
                        $this->getFieldsetEnd() .
                        $this->parent->getInfoBox( wfMessage( 'config-almost-done' )->text() ) .
                        // getRadioSet() builds a set of labeled radio buttons.
@@ -129,7 +135,7 @@ class WebInstallerName extends WebInstallerPage {
                $retVal = true;
                $this->parent->setVarsFromRequest( [ 'wgSitename', '_NamespaceType',
                        '_AdminName', '_AdminPassword', '_AdminPasswordConfirm', '_AdminEmail',
-                       '_Subscribe', '_SkipOptional', 'wgMetaNamespace' ] );
+                       '_Subscribe', '_SkipOptional', 'wgMetaNamespace', 'wgPingback' ] );
 
                // Validate site name
                if ( strval( $this->getVar( 'wgSitename' ) ) === '' ) {
index f8dc8ee..62fe785 100644 (file)
@@ -267,6 +267,7 @@ class WebInstallerOutput {
                }
 ?>
 <?php echo Html::htmlHeader( $this->getHeadAttribs() ); ?>
+
 <head>
        <meta name="robots" content="noindex, nofollow" />
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
index 7dc8cd9..f0eb9f9 100644 (file)
        "config-subscribe": "Падпісацца на [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce сьпіс распаўсюджаньня навінаў пра зьяўленьне новых вэрсіяў].",
        "config-subscribe-help": "Гэта ня вельмі актыўны сьпіс распаўсюджаньня навінаў пра зьяўленьне новых вэрсіяў, які ўключаючы важныя навіны пра бясьпеку.\nВам неабходна падпісацца на яго і абнавіць Вашае ўсталяваньне MediaWiki, калі зьявяцца новыя вэрсіі.",
        "config-subscribe-noemail": "Вы спрабавалі падпісацца на рассылку паведамленьняў пра выхад новых вэрсіяў, не пазначыўшы адрас электроннай пошты.\nКалі ласка, падайце слушны адрас, калі Вы жадаеце падпісацца на рассылку.",
+       "config-pingback": "Дзяліцца зьвесткамі пра гэтую ўсталёўку з распрацоўнікамі MediaWiki.",
        "config-almost-done": "Вы амаль што скончылі!\nАстатнія налады можна прапусьціць і пачаць усталяваньне вікі.",
        "config-optional-continue": "Задаць болей пытаньняў.",
        "config-optional-skip": "Хопіць, проста ўсталяваць вікі.",
        "config-install-extension-tables": "Стварэньне табліцаў для ўключаных пашырэньняў",
        "config-install-mainpage-failed": "Немагчыма ўставіць галоўную старонку: $1",
        "config-install-done": "<strong>Віншуем!</strong>\nВы ўсталявалі MediaWiki.\n\nПраграма ўсталяваньня стварыла файл <code>LocalSettings.php</code>.\nЁн утрымлівае ўсе Вашыя налады.\n\nВам неабходна загрузіць яго і захаваць у карэнную дырэкторыю Вашай вікі (у тую ж самую дырэкторыю, дзе знаходзіцца index.php). Загрузка павінна пачацца аўтаматычна.\n\nКалі загрузка не пачалася, ці Вы яе адмянілі, Вы можаце перазапусьціць яе націснуўшы на спасылку ніжэй:\n\n$3\n\n<strong>Заўвага</strong>: калі Вы гэтага ня зробіце зараз, то створаны файл ня будзе даступны Вам потым, калі Вы выйдзеце з праграмы ўсталяваньня безь яго загрузкі.\n\nКалі Вы гэта зробіце, Вы можаце <strong>[$2 ўвайсьці ў Вашую вікі]</strong>.",
+       "config-install-done-path": "<strong>Віншуем!</strong>\nВы ўсталявалі MediaWiki.\n\nПраграма ўсталёўкі стварыла файл <code>LocalSettings.php</code>. Ён утрымлівае ўсе вашыя налады.\n\nВам трэба спампаваць яго і пакласьці ў <code>$4</code>. Спампоўка павінна пачацца аўтаматычна.\n\nКалі спампоўка не пачалася або вы адмянілі яе, вы можаце пачаць яе наноў, калі націсьніце на наступную спасылку:\n\n$3\n\n<strong>Заўвага:</strong> Калі вы ня зробіце гэта зараз, то створаны файл ня будзе даступны вам па выхадзе з праграмы безь яго спампоўкі.\n\nКалі вы зробіце гэта, вы можаце <strong>[$2 ўвайсьці ў вашую вікі]</strong>.",
        "config-download-localsettings": "Загрузіць <code>LocalSettings.php</code>",
        "config-help": "дапамога",
        "config-help-tooltip": "націсьніце, каб разгарнуць",
index dacc300..3c6d530 100644 (file)
@@ -14,7 +14,8 @@
        "config-information": "তথ্য",
        "config-localsettings-upgrade": "<code>LocalSettings.php</code> ফাইলটি মুছে ফেলা হয়েছে। এই ইন্সটলেশনটি আরো উন্নত করতে দয়া করে <code>$wgUpgradeKey</code> কোডটি বক্সে দিন। আপনি এটি <code>LocalSettings.php</code> -এ পাবেন।",
        "config-localsettings-key": "হালনাগাদ কি",
-       "config-localsettings-badkey": "আপনি যেই চাবিটি দিয়েছেন তা সঠিক নয়।",
+       "config-localsettings-badkey": "আপনি হালনাগাদের যেই চাবিটি দিয়েছেন তা সঠিক নয়।",
+       "config-upgrade-key-missing": "মিডিয়াউইকির একটি বিদ্যমান ইনস্টলেশন সনাক্ত করা হয়েছে। \nএই ইনস্টলেশন হালনাগাদ করার জন্য, দয়া করে নিম্নলিখিত লাইন আপনার <code>LocalSettings.php</code> -এর নিচে স্থাপন করুন:\n\n$1",
        "config-session-error": "সেশন শুরুতে ত্রুটি: $1",
        "config-your-language": "আপনার ভাষা:",
        "config-your-language-help": "ইন্সটল করা সময় ব্যবহারের জন্য ভাষা নির্বাচন করুন।",
@@ -94,6 +95,7 @@
        "config-admin-password-blank": "প্রশাসক অ্যাকাউন্টের জন্য পাসওয়ার্ড প্রবেশ করান।",
        "config-admin-password-mismatch": "আপনি যে দুটি পাসওয়ার্ড দিয়েছেন তারা পরস্পর মেলেনি।",
        "config-admin-email": "ইমেইল ঠিকানা:",
+       "config-admin-error-bademail": "আপনি একটি অবৈধ ইমেল ঠিকানা দিয়েছেন।",
        "config-optional-continue": "আরও প্রশ্ন জিজ্ঞেস করুন।",
        "config-optional-skip": "আমি ইতিমধ্যেই বিরক্ত হয়ে গেছি, উইকিটি ইন্সটল করো।",
        "config-profile": "ব্যবহারকারী অধিকার প্রোফাইল:",
index fd4456b..8de5c82 100644 (file)
        "config-subscribe": "Bitte die Mailingliste [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mitteilungen zu Versionsveröffentlichungen] abonnieren.",
        "config-subscribe-help": "Es handelt sich hierbei um eine Mailingliste mit wenigen Aussendungen, die für Mitteilungen zu Versionsveröffentlichungen, einschließlich wichtiger Sicherheitsveröffentlichungen, genutzt wird.\nDiese Mailingliste sollte abonniert werden. Zudem sollte die MediaWiki-Installation stets aktualisiert werden, sobald eine neue Programmversion veröffentlicht wurde.",
        "config-subscribe-noemail": "Beim Abonnieren der Mailingliste mit Mitteilungen zu Versionsveröffentlichungen wurde keine E-Mail-Adresse angegeben.\nBitte eine E-Mail-Adresse angeben, sofern die Mailingliste abonniert werden soll.",
+       "config-pingback": "Daten über diese Installation mit den MediaWiki-Entwicklern teilen.",
+       "config-pingback-help": "Wenn du diese Option auswählst, pingt MediaWiki regelmäßig https://www.mediawiki.org mit Basisdaten über diese MediaWiki-Instanz an. Diese Daten enthalten zum Beispiel den Systemtyp, die PHP-Version und das ausgewählte Datenbank-Backend. Die Wikimedia Foundation teilt diese Daten mit MediaWiki-Entwicklern, um dabei zu helfen, zukünftigen Entwicklungsaufwand zu leiten.",
        "config-almost-done": "Der Vorgang ist fast abgeschlossen!\nDie verbleibenden Konfigurationseinstellungen können übersprungen und das Wiki umgehend installiert werden.",
        "config-optional-continue": "Ja, es sollen weitere Konfigurationseinstellungen vorgenommen werden.",
        "config-optional-skip": "Nein, das Wiki soll nun installiert werden.",
index 79383f3..dbe4266 100644 (file)
        "config-subscribe": "Subscribe to the [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce release announcements mailing list].",
        "config-subscribe-help": "This is a low-volume mailing list used for release announcements, including important security announcements.\nYou should subscribe to it and update your MediaWiki installation when new versions come out.",
        "config-subscribe-noemail": "You tried to subscribe to the release announcements mailing list without providing an email address.\nPlease provide an email address if you wish to subscribe to the mailing list.",
+       "config-pingback": "Share data about this installation with MediaWiki developers.",
+       "config-pingback-help": "If you select this option, MediaWiki will periodically ping https://www.mediawiki.org with basic data about this MediaWiki instance. This data includes, for example, the type of system, PHP version, and chosen database backend. The Wikimedia Foundation shares this data with MediaWiki developers to help guide future development efforts.",
        "config-almost-done": "You are almost done!\nYou can now skip the remaining configuration and install the wiki right now.",
        "config-optional-continue": "Ask me more questions.",
        "config-optional-skip": "I'm bored already, just install the wiki.",
index b9d5086..dfcf1d3 100644 (file)
@@ -78,6 +78,6 @@
        "config-install-user-alreadyexists": "Kasutaja \"$1\" on juba olemas",
        "config-install-tables": "Tabelite loomine",
        "config-help": "abi",
-       "mainpagetext": "'''MediaWiki tarkvara on edukalt paigaldatud.'''",
+       "mainpagetext": "<strong>MediaWiki tarkvara on paigaldatud.</strong>",
        "mainpagedocfooter": "Vikitarkvara kasutamise kohta leiad lisateavet [https://meta.wikimedia.org/wiki/Help:Contents juhendist].\n\n== Alustamine ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Häälestussätete loend]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki KKK]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki versiooniuuenduste postiloend]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources MediaWiki lokaliseerimine]"
 }
index 0a61173..7dbca51 100644 (file)
        "config-sqlite-name-help": "Valitse nimi, joka yksilöi tämän wikin.\nÄlä käytä välilyöntejä tai viivoja.\nNimeä käytetään SQLite-tietokannan tiedostonimessä.",
        "config-sqlite-dir-unwritable": "Hakemistoon ”$1” kirjoittaminen epäonnistui.\nMuuta hakemiston käyttöoikeuksia siten, että palvelinohjelmisto voi kirjoittaa siihen ja yritä uudelleen.",
        "config-sqlite-readonly": "Tiedostoon <code>$1</code> ei voi kirjoittaa.",
+       "config-sqlite-cant-create-db": "Tietokantatiedostoa <code>$1</code> ei voitu luoda.",
        "config-sqlite-fts3-downgrade": "PHP:stä puuttuu FTS3-tuki. Poistetaan ominaisuus käytöstä tietokantatauluista.",
        "config-can-upgrade": "Tietokanta sisältää jo MediaWiki tauluja.\nPäivitä ne MediaWiki-versioon $1 painamalla <strong>Jatka</strong>.",
        "config-upgrade-done": "Päivitys valmis.\n\nVoit [$1 aloittaa wikin käytön].\n\nNapsauta alla olevaa painiketta, jos haluat luoda uudelleen <code>LocalSettings.php</code>-tiedoston.\nTämä '''ei ole suositeltavaa''', jos wikissäsi ei ole ongelmia.",
        "config-upgrade-done-no-regenerate": "Päivitys valmis.\n\nVoit [$1 aloittaa wikin käytön].",
        "config-regenerate": "Luo LocalSettings.php uudelleen →",
        "config-show-table-status": "Kysely <code>SHOW TABLE STATUS</code> epäonnistui!",
+       "config-unknown-collation": "<strong>Varoitus:</strong> Tietokanta käyttää tunnistamatonta lajittelua.",
        "config-db-web-help": "Valitse käyttäjänimi ja salasana joita palvelin käyttää muodostaessaan yhteyttä tietokantapalvelimeen wikin normaalin toiminnan aikana.",
        "config-db-web-account-same": "Käytä samaa tiliä kuin asennuksessa",
        "config-db-web-create": "Lisää tili, jos sitä ei ole jo olemassa",
        "config-mssql-auth": "Varmennuksen tyyppi:",
        "config-mssql-install-auth": "Valitse varmennuksen tyyppi, jota käytetään yhdistäessä tietokantaan asennuksen aikana.\nJos valitset \"{{int:config-mssql-windowsauth}}\", käytetään verkkopalvelimen käyttäjän kirjautumistietoja.",
        "config-mssql-web-auth": "Valitse varmennuksen tyyppi, jota verkkopalvelin käyttää yhdistäessään tietokantapalvelimeen wikin tavallisen toiminnan aikana.\nJos valitset \"{{int:config-mssql-windowsauth}}\", käytetään verkkopalvelimen käyttäjän kirjautumistietoja.",
+       "config-mssql-windowsauth": "Windows-varmennus",
        "config-site-name": "Wikin nimi",
        "config-site-name-help": "Tämä näkyy selaimen otsikkona ja muissa kohdissa.",
        "config-site-name-blank": "Kirjoita sivuston nimi.",
        "config-ns-site-name": "Sama kuin wikin nimi: $1",
        "config-ns-other": "Muu (määritä)",
        "config-ns-other-default": "MinunWiki",
+       "config-project-namespace-help": "Wikipedian esimerkkiä seuraten monien wikien käytäntösivut ovat erillään sisältösivuista '''projektinimiavaruudessa'''.\nTämän nimiavaruuden kaikki sivujen nimet alkavat etuliitteellä, jonka voit määrittää tässä.\nYleensä tämä etuliite pohjautuu wikin nimeen, mutta siinä ei saa olla välimerkkejä kuten \"#\" tai \":\".",
        "config-ns-invalid": "Määritelty nimiavaruus \"<nowiki>$1</nowiki>\" on virheellinen.\nSyötä joku muu nimiavaruus.",
        "config-ns-conflict": "Määritelty nimiavaruus \"<nowiki>$1</nowiki>\" on ristiriidassa MediaWikin oletusnimiavaruuksien kanssa.\nSyötä joku muu nimiavaruus.",
        "config-admin-box": "Ylläpitäjän tili",
        "config-install-extension-tables": "Luodaan tauluja käyttöönotetuille laajuennuksille",
        "config-install-mainpage-failed": "Etusivun lisääminen ei onnistunut: $1",
        "config-install-done": "<strong>Onnittelut!</strong>\nOlet asentanut MediaWikin.\n\nAsennusohjelma on luonut <code>LocalSettings.php</code> -tiedoston.\nSiinä on kaikki MediaWikin asetukset.\n\nLataa tiedosto ja laita se MediaWikin asennushakemistoon (sama kuin missä on index.php). Lataamisen olisi pitänyt alkaa automaattisesti.\n\nMikäli latausta ei tarjottu tai keskeytit latauksen, käynnistä se uudestaan tästä linkistä:\n\n$3\n\n<strong>Huom:</strong> Mikäli et nyt lataa tiedostoa, luotu tiedosto ei ole saatavissa myöhemmin, jos poistut asennuksesta lataamatta sitä.\n\nKun olet laittanut tiedoston oikeaan paikkaan, voit <strong>[$2 mennä wikiisi]</strong>.",
+       "config-install-done-path": "<strong>Onnittelut!</strong>\nOlet asentanut MediaWikin.\n\nAsennusohjelma on luonut <code>LocalSettings.php</code> -tiedoston.\nSiinä on kaikki MediaWikin asetukset.\n\nLataa tiedosto ja laita se sijaintiin <code>$4</code>. Lataamisen olisi pitänyt alkaa automaattisesti.\n\nMikäli latausta ei tarjottu tai keskeytit latauksen, käynnistä se uudestaan tästä linkistä:\n\n$3\n\n<strong>Huom:</strong> Mikäli et nyt lataa tiedostoa, luotu tiedosto ei ole saatavissa myöhemmin, jos poistut asennuksesta lataamatta sitä.\n\nKun olet laittanut tiedoston oikeaan paikkaan, voit <strong>[$2 mennä wikiisi]</strong>.",
        "config-download-localsettings": "Lataa <code>LocalSettings.php</code>",
        "config-help": "ohje",
        "config-help-tooltip": "Klikkaa laajentaaksesi",
index d73f61b..a12e6a0 100644 (file)
        "config-subscribe": "Abonnez-vous à la [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce liste d'annonce des nouvelles versions]",
        "config-subscribe-help": "Il s'agit d'une liste de diffusion à faible volume utilisée servant à annoncer les nouvelles versions, y compris les versions améliorant la sécurité du logiciel.\nVous devriez y souscrire et mettre à jour votre version de MediaWiki lorsque de nouvelles versions sont publiées.",
        "config-subscribe-noemail": "Vous avez essayé de vous abonner à la liste de diffusion des communiqués, sans fournir une adresse courriel ! S'il vous plaît, fournir une adresse électronique si vous souhaitez vous abonner à la liste de diffusion.",
+       "config-pingback": "Partager des données au sujet de cette installation avec les développeurs de MediaWiki.",
+       "config-pingback-help": "Si vous sélectionnez cette option, MediaWiki fera périodiquement un ping https://www.mediawiki.org avec les données de base sur cette instance de MediaWiki. Ces données incluent, par exemple, le type de système, la version de PHP et de base de données arrière. La Fondation Wikimedia partage ces données avec les développeurs de MediaWiki pour aider à orienter les futurs efforts de développement.",
        "config-almost-done": "Vous avez presque fini !\nVous pouvez passer la configuration restante et installer immédiatement le wiki.",
        "config-optional-continue": "Me poser davantage de questions.",
        "config-optional-skip": "J’en ai assez, installer simplement le wiki.",
index d57e19f..326f947 100644 (file)
@@ -5,7 +5,8 @@
                        "Toliño",
                        "아라",
                        "Vivaelcelta",
-                       "Macofe"
+                       "Macofe",
+                       "Banjo"
                ]
        },
        "config-desc": "O programa de instalación de MediaWiki",
        "config-subscribe": "Subscríbase á [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce lista de correo de anuncios sobre lanzamentos].",
        "config-subscribe-help": "Esta é unha lista de correos de baixo volume usada para anuncios sobre lanzamentos de novas versións, incluíndo avisos de seguridade importantes.\nDebería subscribirse a ela e actualizar a súa instalación MediaWiki cando saian as novas versións.",
        "config-subscribe-noemail": "Intentou subscribirse á lista de correo dos anuncios de novos lanzamentos sen proporcionar o enderezo de correo electrónico.\nDea un enderezo de correo electrónico se quere efectuar a subscrición á lista de correo.",
+       "config-pingback": "Compartir datos de esta instalación cos desenvolvedores de MediaWiki",
+       "config-pingback-help": "Se seleccionas esta opción, MediaWiki enviará periodicamente unha mensaxe a https://www.mediawiki.org con datos básicos sobre esta instancia Mediawiki. Estos datos inclúen, por exemplo, o tipo de sistema, versión de PHP e a base de datos escollida. A Fundación Wikimedia comparte estos datos cos desenvolvedores de MediaWiki para axudar a guiar o traballo futuro de desenvolvemento.",
        "config-almost-done": "Xa case rematou!\nNeste paso pode saltar o resto da configuración e instalar o wiki agora mesmo.",
        "config-optional-continue": "Facédeme máis preguntas.",
        "config-optional-skip": "Xa estou canso. Instalade o wiki.",
index 6f519ec..f156a00 100644 (file)
        "config-subscribe": "להירשם ל[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה עם הודעות על גרסאות חדשות].",
        "config-subscribe-help": "זוהי רשימת תפוצה עם הודעות מעטות שמשמשת להודעות על הוצאת גרסאות, כולל עדכוני אבטחה חשובים.\nמומלץ להירשם אליה ולעדכן את מדיה־ויקי כאשר יוצאות גרסאות חדשות.",
        "config-subscribe-noemail": "ניסית להירשם לרשימת תפוצה של הודעות בלי לתת כתובת דוא\"ל.\nנא לתת כתובת דוא\"ל אם ברצונך להירשם לרשימת התפוצה.",
+       "config-pingback": "לשתף נתונים אודות ההתקנה הזו עם מפתחי מדיה־ויקי.",
        "config-almost-done": "כמעט סיימת!\nאפשר לדלג על שאר ההגדרות ולהתקין את הוויקי כבר עכשיו.",
        "config-optional-continue": "הצגת שאלות נוספות.",
        "config-optional-skip": "משעמם לי, תתקינו לי כבר את הוויקי הזה.",
index ea51e21..5406be1 100644 (file)
        "config-install-extension-tables": "有効にした拡張機能のためのテーブルを作成しています",
        "config-install-mainpage-failed": "メインページを挿入できませんでした: $1",
        "config-install-done": "<strong>おめでとうございます!</strong>\nMediaWikiのインストールに成功しました。\n\n<code>LocalSettings.php</code>ファイルが生成されました。\nこのファイルはすべての設定を含んでいます。\n\nこれをダウンロードして、ウィキをインストールした基準ディレクトリ (index.phpと同じディレクトリ) に設置する必要があります。ダウンロードは自動的に開始されるはずです。\n\nダウンロードが開始されていない場合、またはダウンロードをキャンセルした場合は、下記のリンクをクリックしてダウンロードを再開できます:\n\n$3\n\n<strong>注意:</strong> この生成された設定ファイルをダウンロードせずにインストールを終了すると、このファイルは利用できなくなります。\n\n上記の作業が完了すると、<strong>[$2 ウィキに入る]</strong>ことができます。",
+       "config-install-done-path": "<strong>おめでとうございます!</strong>\nMediaWikiのインストールに成功しました。\n\n<code>LocalSettings.php</code>ファイルが生成されました。\nこのファイルはすべての設定を含んでいます。\n\nこれをダウンロードして、<code>$4</code> に設置する必要があります。ダウンロードは自動的に開始されるはずです。\n\nダウンロードが開始されていない場合、またはダウンロードをキャンセルした場合は、下記のリンクをクリックしてダウンロードを再開できます:\n\n$3\n\n<strong>注意:</strong> この生成された設定ファイルをダウンロードせずにインストールを終了すると、このファイルは利用できなくなります。\n\n上記の作業が完了すると、<strong>[$2 ウィキに入る]</strong>ことができます。",
        "config-download-localsettings": "<code>LocalSettings.php</code> をダウンロード",
        "config-help": "ヘルプ",
        "config-help-tooltip": "クリックで展開",
index 5e9c34d..d3405d2 100644 (file)
@@ -61,7 +61,7 @@
        "config-unicode-pure-php-warning": "<strong>경고:</strong> 유니코드 정규화를 처리할 [http://pecl.php.net/intl intl PECL 확장 기능]을 사용할 수 없기 때문에 느린 pure-PHP 구현을 대신 사용합니다.\n트래픽이 높은 사이트에서 실행하시려면 [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 유니코드 정규화]를 읽어보셔야 합니다.",
        "config-unicode-update-warning": "<strong>경고:</strong> 유니코드 정규화 래퍼의 설치된 버전은 [http://site.icu-project.org/ ICU 프로젝트]의 라이브러리의 이전 버전을 사용합니다.\n만약 유니코드를 사용하는 것에 대해 우려가 된다면 [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 업그레이드]해야합니다.",
        "config-no-db": "적절한 데이터베이스 드라이버를 찾을 수 없습니다! PHP용 데이터베이스 드라이버를 설치해야 합니다.\n다음 데이터베이스 {{PLURAL:$2|유형을 지원합니다}}: $1.\n\nPHP를 직접 컴파일했다면, 예를 들어 <code>./configure --with-mysql</code>을 사용하여, 데이터베이스 클라이언트를 활성화하도록 다시 설정하세요.\n데비안이나 우분투 패키지에서 PHP를 설치했다면 <code>php5-mysql</code> 모듈도 설치해야 합니다.",
-       "config-outdated-sqlite": "<strong>경고:</strong> 최소인 $2 버전보다 낮은 SQLite $1(이)가 있습니다. SQLite를 사용할 수 없습니다.",
+       "config-outdated-sqlite": "<strong>경고:</strong> 최소 요구 버전 $2 보다 낮은 SQLite $1이(가) 있습니다. SQLite를 사용할 수 없습니다.",
        "config-no-fts3": "<strong>경고:</strong> SQLite를 [//sqlite.org/fts3.html FTS3 모듈] 없이 컴파일하며, 검색 기능은 백엔드에 사용할 수 없습니다.",
        "config-pcre-old": "<strong>치명:</strong> PCRE $1 또는 그 이상이 필요합니다.\nPHP 바이너리는 PCRE $2에 연결되어 있습니다. [https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE 자세한 정보].",
        "config-pcre-no-utf8": "<strong>치명:</strong> PHP의 PCRE 모듈은 RCRE_UTF8 지원 없이 컴파일된 것 같습니다.\n미디어위키가 올바르게 작동하려면 UTF-8을 지원해야 합니다.",
@@ -80,8 +80,8 @@
        "config-no-scaling": "GD 라이브러리나 ImageMagick를 찾을 수 없습니다.\n그림 섬네일이 비활성화됩니다.",
        "config-no-uri": "<strong>오류:</strong> 현재 URI를 확인할 수 없습니다.\n설치가 중단되었습니다.",
        "config-no-cli-uri": "<strong>경고:</strong> 기본값을 사용하여 <code>--scriptpath</code>를 지정하지 않았습니다: <code>$1</code>.",
-       "config-using-server": "\"<nowiki>$1</nowiki>\"(을)를 서버 이름으로 사용합니다.",
-       "config-using-uri": "\"<nowiki>$1$2</nowiki>\"(을)를 서버 URL로 사용합니다.",
+       "config-using-server": "\"<nowiki>$1</nowiki>\" 서버 이름을 사용 중입니다.",
+       "config-using-uri": "\"<nowiki>$1$2</nowiki>\" 서버 URL을 사용 중입니다.",
        "config-uploads-not-safe": "<strong>경고:</strong> 올리기에 대한 기본 디렉터리(<code>$1</code>)는 임의의 스크립트 실행에 취약합니다.\n미디어위키는 보안 위협 때문에 모든 올려진 파일을 검사하지만, 올리기를 활성화하기 전에 [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security 이 보안 취약점을 해결할 것]을 매우 권장합니다.",
        "config-no-cli-uploads-check": "<strong>경고:</strong> 올리기를 위한 기본 디렉터리(<code>$1</code>)는 CLI를 설치하는 동안 임의의 스크립트 실행에 대한 취약점에 대해 검사되지 않습니다.",
        "config-brokenlibxml": "시스템에 버그가 있는 PHP와 libxml2의 조합이 있으며 미디어위키나 다른 웹 애플리케이션에 숨겨진 데이터 손상을 일으킬 수 있습니다.\nlibxml2 2.7.3 이후 버전으로 업그레이드하세요. ([https://bugs.php.net/bug.php?id=45996 PHP에 제기한 버그])\n설치가 중단되었습니다.",
        "config-db-wiki-help": "정상적인 위키 작업 동안 데이터베이스에 연결하는 데 사용할 사용자 이름과 비밀번호를 입력하세요.\n계정이 존재하지 않고 설치 계정에 충분한 권한이 있는 경우 이 사용자 계정은 위키를 작동하는 데 필요한 최소 권한으로 만들어집니다.",
        "config-db-prefix": "데이터베이스 테이블 접두어:",
        "config-db-prefix-help": "여러 위키 사이 또는 미디어위키와 다른 웹 애플리케이션 사이에 하나의 데이터베이스를 공유해야 하는 경우, 충돌을 피하기 위해 모든 테이블 이름에 접두어를 추가하도록 선택할 수 있습니다.\n공백을 사용하지 마세요.\n\n이 필드는 일반적으로 비어 있습니다.",
-       "config-mysql-old": "MySQL $1 ì\9d´ì\83\81ì\9d´ í\95\84ì\9a\94í\95\98ë\82\98 $2(ì\9d´)ê°\80 있습니다.",
+       "config-mysql-old": "MySQL $1 ì\9d´ì\83\81ì\9d´ í\95\84ì\9a\94í\95©ë\8b\88ë\8b¤. $2ì\9d´(ê°\80) 있습니다.",
        "config-db-port": "데이터베이스 포트:",
        "config-db-schema": "미디어위키에 대한 스키마:",
        "config-db-schema-help": "보통 이 스키마는 문제가 없습니다.\n필요한 경우에만 바꾸세요.",
        "config-invalid-schema": "미디어위키 \"$1\"에 대한 스키마가 잘못됐습니다.\nASCII 글자 (a-z, A-Z), 숫자 (0-9), 밑줄 (_)과 하이픈 (-)만 사용하세요.",
        "config-db-sys-create-oracle": "설치 관리자는 새 계정을 만들기 위한 SYSDBA 계정만을 지원합니다.",
        "config-db-sys-user-exists-oracle": "\"$1\" 사용자 계정이 이미 존재합니다. SYSDBA는 새 계정을 만드는 데에만 사용할 수 있습니다!",
-       "config-postgres-old": "PostgreSQL $1 ì\9d´ì\83\81ì\9d´ í\95\84ì\9a\94í\95\98ë\82\98 $2(ì\9d´)ê°\80 있습니다.",
+       "config-postgres-old": "PostgreSQL $1 ì\9d´ì\83\81ì\9d´ í\95\84ì\9a\94í\95©ë\8b\88ë\8b¤. $2ì\9d´(ê°\80) 있습니다.",
        "config-mssql-old": "Microsoft SQL 서버 $1 이상의 버전이 필요합니다. 현재 버전은 $2입니다.",
        "config-sqlite-name-help": "위키를 식별하기 위한 이름을 선택하세요.\n공백이나 하이픈을 사용하지 마십시오.\nSQLite 데이터 파일 이름에 사용됩니다.",
        "config-sqlite-parent-unwritable-group": "<code><nowiki>$1</nowiki></code> 데이터 디렉토리를 만들 수 없으며, 이는 웹 서버는 상위 디렉토리인 <code><nowiki>$2</nowiki></code>에 쓸 수 없기 때문입니다.\n\n설치 관리자는 웹 서버로 실행 중인 사용자를 지정할 수 없습니다.\n계속하려면 웹 서버가 쓸 수 있는 <code><nowiki>$3</nowiki></code> 디렉토리를 만드세요.\n유닉스/리눅스 시스템에서의 수행:\n\n<pre>cd $2\nmkdir $3\nchgrp $4 $3\nchmod g+w $3</pre>",
        "config-subscribe": "[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce 릴리스 발표 메일링 리스트]를 구독합니다.",
        "config-subscribe-help": "중요한 보안 발표를 포함한 배포판 발표에 사용되는 저용량 메일링 리스트입니다.\n이 리스트를 구독하고 새 버전이 나올 때 미디어위키 설치를 업데이트해야 합니다.",
        "config-subscribe-noemail": "이메일 주소를 입력하지 않고 릴리스 발표 메일링 리스트에 가입하려 합니다.\n메일링 리스트에 가입하고자 할 경우 이메일 주소를 입력하세요.",
+       "config-pingback": "본 설치에 관한 데이터를 미디어위키 개발자와 공유합니다.",
+       "config-pingback-help": "이 옵션을 선택하면 미디어위키는 주기적으로 이 미디어위키 인스턴스에 대한 기본 데이터를 가지고 https://www.mediawiki.org에 핑을 합니다. 이 데이터에는 이를테면 시스템의 종류, PHP 버전, 선택한 데이터베이스 백엔드를 포함합니다. 위키미디어 재단은 이 데이터를 미디어위키 개발자들과 공유하여 향후 개발 활동의 길잡이에 도움을 줍니다.",
        "config-almost-done": "거의 다 완료했습니다!\n이제 남은 설정을 생략하고 지금 바로 위키를 설치할 수 있습니다.",
        "config-optional-continue": "더 많은 질문을 물어보세요.",
        "config-optional-skip": "지겨워요, 그냥 위키를 설치할래요.",
        "config-memcache-needservers": "캐시 종류로 Memcached를 선택했지만 어떠한 서버도 지정하지 않았습니다.",
        "config-memcache-badip": "Memcached에 대해 잘못된 IP 주소를 입력했습니다: $1.",
        "config-memcache-noport": "Memcached 서버에 사용할 포트를 지정하지 않았습니다: $1.\n포트를 모를 경우 기본 값은 11211입니다.",
-       "config-memcache-badport": "Memcached 포트 번호는 $1(와)과 $2 사이여야 합니다.",
+       "config-memcache-badport": "Memcached 포트 번호는 $1와(과) $2 사이여야 합니다.",
        "config-extensions": "확장 기능",
        "config-extensions-help": "위에 나열된 확장 기능이 <code>./extensions</code>에서 발견되었습니다.\n\n추가적인 설정이 필요할 수 있습니다만 지금 활성화시킬 수 있습니다.",
        "config-skins": "스킨",
index a39d3a1..3343db7 100644 (file)
        "config-subscribe": "Donn de [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce \n<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i>-Leß met de Aanköndijonge vum MehdijaWikki] abonnehre.",
        "config-subscribe-help": "Do kumme bloß winnish Meddeilunge un di jonn övver neu Versiohne vom MediaWiki un weeshtejje Saache vun däm sing Sesherheit.\nDo sullts se abbonneere, un Ding MediWiki_Projramme op der neue Shtand bränge, wann neu Version eruß kumme.",
        "config-subscribe-noemail": "Do has versöhk, der ohne en Addräß för Ding <i lang=\"en\">e-mail<i> aanzejävve, de Aanköndijonge för Aanköndijunge för neue Versione ze abboneere. Jivv en Addräß aan, wann De di Aanköndijonge hann wells.",
+       "config-pingback": "Jivv Dahte övver heh di Enschtallazjuhn vum Mehdijawikki aan de Äntwerkere.",
        "config-almost-done": "Do bes beinah dorsch!\nDo künnts jez der Räß vun de einzel Enschtällonge övverjonn, un et Wiki tiräktemang fähdesch opsäze.",
        "config-optional-continue": "De wells noch mih Frohre jeschtallt krijje un noch mih Enschtällonge maache?",
        "config-optional-skip": "Nä, lohß dä Ömshtand, donn eifarr_et Wiki opsäze.",
index 193e445..423926b 100644 (file)
        "config-install-extension-tables": "Tworzenie tabel dla aktywnych rozszerzeń",
        "config-install-mainpage-failed": "Nie udało się wstawić strony głównej: $1",
        "config-install-done": "<strong>'''Gratulacje!</strong>\nUdało Ci się zainstalować MediaWiki.\n\nInstalator wygenerował plik konfiguracyjny <code>LocalSettings.php</code>.\n\nMusisz go pobrać i umieścić w katalogu głównym Twojej instalacji wiki (tym samym katalogu co index.php). Pobieranie powinno zacząć się automatycznie.\n\nJeżeli pobieranie nie zostało zaproponowane lub jeśli użytkownik je anulował, można ponownie uruchomić pobranie klikając poniższe łącze:\n\n$3\n\n<strong>Uwaga</strong>: Jeśli nie zrobisz tego teraz, wygenerowany plik konfiguracyjny nie będzie już dostępny po zakończeniu instalacji.\n\nPo załadowaniu pliku konfiguracyjnego możesz <strong>[$2 wejść na wiki]</strong>.",
+       "config-install-done-path": "<strong>Gratulacje!</strong>\nZainstalowałeś właśnie MediaWiki.\n\nInstalator wygenerował plik <code>LocalSettings.php</code>.\nZawiera całą Twoją konfigurację.\n\nMusisz go pobrać i umieścić w <code>$4</code>. Pobieranie powinno rozpocząć się automatycznie.\n\nJeżeli nie pojawiła się informacja o pobieraniu lub jeżeli ja anulowałeś, kliknij poniższy link:\n\n$3\n\n<strong>Uwaga:</strong> Jeżeli nie zrobisz tego teraz, wygenerowany plik konfiguracyjny nie będzie potem dostępny, jeżeli wyjdziesz z instalacji bez jego pobrania.\n\nGdy to będzie zrobione, możesz <strong>[$2 wejść na swoją wiki]</strong>.",
        "config-download-localsettings": "Pobierz <code>LocalSettings.php</code>",
        "config-help": "pomoc",
        "config-help-tooltip": "kliknij, aby rozwinąć",
index 69a6830..6a1dd08 100644 (file)
        "config-subscribe": "Used as label for the installer checkbox",
        "config-subscribe-help": "\"Low-volume\" in this context means that there will be few e-mails to that mailing list per time period.",
        "config-subscribe-noemail": "Error text in MediaWiki installer.",
+       "config-pingback": "Option in the MediaWiki installer to submit data about this installation to MediaWiki.org.",
+       "config-pingback-help": "Explains what data will be shared if the user chooses to submit data to MediaWiki.org.",
        "config-almost-done": "Status message in the MediaWiki installer.",
        "config-optional-continue": "Option in the MediaWiki installer to make a more fine-tuned installation.",
        "config-optional-skip": "Option in the MediaWiki installer to start executing the actual installation and stop asking questions.",
index 34ef3e8..418b4ff 100644 (file)
        "config-subscribe": "Подписаться на [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce рассылку новостей о появлении новых версий MediaWiki].",
        "config-subscribe-help": "Это список рассылки с малым числом сообщений, используется для анонса новых выпусков и сообщений о проблемах с безопасностью.\nВам следует подписаться на него и обновлять движок MediaWiki, по мере выхода новых версий.",
        "config-subscribe-noemail": "Вы попытались подписаться на список рассылки уведомлений о новых выпусках без указания адреса электронной почты.\nУкажите адрес электронной почты, если вы хотите подписаться на список рассылки.",
+       "config-pingback": "Поделиться сведениями об этой установке с разработчикам MediaWiki.",
+       "config-pingback-help": "Если вы выберите этот вариант, MediaWiki будет периодически отправлять на https://www.mediawiki.org основные сведения об этом экземпляре MediaWiki. К этим данным относятся, в частности, тип операционной системы, версия PHP и выбранная СУБД. Фонда Викимедиа делится этими данными с разработчиками MediaWiki, чтобы помочь им в проведении будущих разработок.",
        "config-almost-done": "Вы почти у цели!\nОстальные настройки можно пропустить и приступить к установке вики.",
        "config-optional-continue": "Произвести тонкую настройку",
        "config-optional-skip": "Хватит, установить вики",
index 6965a15..914618b 100644 (file)
@@ -1,18 +1,22 @@
 {
        "@metadata": {
                "authors": [
-                       "VASANTH S.N."
+                       "VASANTH S.N.",
+                       "Vishwanatha Badikana"
                ]
        },
-       "config-title": "ಮೀಡಿಯಾವಿಕಿ ಆವೃತ್ತಿ $1 ರ ಅನುಸ್ಥಾಪನೆ",
+       "config-desc": "ಮೀಡಿಯ ವಿಕಿದ ಪ್ರತಿಸ್ಟಾಪನೆ",
+       "config-title": "ಮೀಡಿಯಾವಿಕಿ ಆವೃತ್ತಿ $1 ರ ಪ್ರತಿಸ್ಟಾಪನೆ",
        "config-information": "ಮಾಹಿತಿ",
-       "config-localsettings-key": "ಉನ್ನತೀಕರಣ ಕೀಲಿ",
-       "config-session-error": "ಅವಧಿ ಪ್ರಾರಂಭದ ದೋಷ: $1",
+       "config-localsettings-upgrade": "ಒಂಜಿ<code>LocalSettings.php</code>ದ ಕಡತೊ ಪತ್ತೆ ಆತ್ಂಡ್.  ಈ ಪ್ರತಿಸ್ಟಾಪನೆನ್ ಪೊಸತ್ ಮಲ್ಪೆರೆ, ದಯದೀಡ್ದ್ ತಿರ್ತ್‌ದ ಪಟ್ಟಿಗೆದ <code>$wgUpgradeKey</code>ದ ಬಿಲೆನ್ ನಮೂದಿಸಲೆ.\nಈರ್ <code>LocalSettings.php</code>ನ್ ನಾಡೊಲಿ",
+       "config-localsettings-cli-upgrade": "ಒಂಜಿ<code>LocalSettings.php</code>ದ ಕಡತೊ ಪತ್ತೆ ಆತ್ಂಡ್.  ಈ ಪ್ರತಿಸ್ಟಾಪನೆನ್ ಪೊಸತ್ ಮಲ್ಪೆರೆ, ದಯದೀಡ್ದ್ ತಿರ್ತ್‌ದ ಪಟ್ಟಿಗೆದ <code>$wgUpgradeKey</code>ದ ಬಿಲೆನ್ ನಮೂದಿಸಲೆ.\nದಯಮಲ್ತ್ <code>LocalSettings.php</code>ಗ್ ಬದಲಾದ್  ಬಲಿಪಾಲೆ",
+       "config-localsettings-key": "ಏಲಿಗೆದ ಕೀ",
+       "config-session-error": "ಸಬೆ ಸುರುಮಲ್ಪುನ ದೋಸೊ: $1",
        "config-your-language": "ಇರೆನಾ ಬಾಸೆ",
-       "config-wiki-language": "ವಿà²\95ಿ à²­à²¾à²·ೆ:",
+       "config-wiki-language": "ವಿà²\95ಿ à²¬à²¾à²¸ೆ:",
        "config-back": "← ಪಿರ",
        "config-continue": "ಮುಂದುವರೆಸಾಲೆ →",
-       "config-page-language": "ಭಾಸೆ",
+       "config-page-language": "ಬಾಸೆ",
        "config-page-welcome": "ಮಾಧ್ಯಮವಿಕಿಗ್ ಸ್ವಾಗತ",
        "config-page-dbconnect": "ದತ್ತಾಂಶಸಂಚಯಗ್ ಸಂಪರ್ಕಕೊರ್ಲೆ",
        "config-page-name": "ಪುದರ್",
index 8b8d02d..6b5bfe0 100644 (file)
@@ -7,6 +7,7 @@
                ]
        },
        "config-information": "信息",
+       "config-back": "← 转去",
        "config-page-language": "闲话",
        "mainpagetext": "<strong>MediaWiki安装好哉。</strong>",
        "mainpagedocfooter": "请访问[https://meta.wikimedia.org/wiki/Help:Contents 用户手册]以获得使用此维基软件个信息!\n\n== 入门 ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings MediaWiki 配置设置列表]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki 常见问题解答]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki 发布邮件列表]"
index 07e1fc3..84cea99 100644 (file)
        "config-subscribe": "订阅[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce 发行公告邮件列表]。",
        "config-subscribe-help": "此低流量的邮件列表仅用于发行公告,其中包括重要安全公告。请订阅该列表以便在新的版本推出时升级您的MediaWiki。",
        "config-subscribe-noemail": "您选择了订阅发行公告邮件列表,但没有提供电子邮件地址。请提供一个电子邮件地址以订阅邮件列表。",
+       "config-pingback": "与MediaWiki开发人员分享有关此安装程序的数据。",
+       "config-pingback-help": "如果您选择此选项,MediaWiki将定期与https://www.mediawiki.org通信,传输与此MediaWiki实例相关的基础数据。此数据包括例如系统类型、PHP版本和选择的数据库后端。维基媒体基金会与MediaWiki开发人员分享此数据,以帮助引导将来的开发计划。",
        "config-almost-done": "您几乎已经完成了!现在您可以跳过剩下的配置流程并立即安装wiki。",
        "config-optional-continue": "多问我一些问题吧。",
        "config-optional-skip": "我已经不耐烦了,赶紧安装我的wiki。",
index 53d001e..dab2f26 100644 (file)
@@ -15,7 +15,8 @@
                        "LNDDYL",
                        "NigelSoft",
                        "Macofe",
-                       "Reke"
+                       "Reke",
+                       "Suchichi02"
                ]
        },
        "config-desc": "MediaWiki 安裝程式",
        "config-help-tooltip": "點選以展開",
        "config-nofile": "查無檔案 \"$1\",是否已被刪除?",
        "config-extension-link": "您是否了解您的 Wiki 支援 [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions 擴充套件]?\n\n\n您可以瀏覽 [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category 擴充套件分類] 或 [https://www.mediawiki.org/wiki/Extension_Matrix 擴充套件資料表] 以取得相關的資訊。",
-       "mainpagetext": "<strong>已成功安裝 MediaWiki。</strong>",
+       "mainpagetext": "<strong>已安裝 MediaWiki。</strong>",
        "mainpagedocfooter": "請參閱 [https://meta.wikimedia.org/wiki/Help:Contents 使用者手冊] 以取得使用 Wiki 的相關訊息!\n\n== 新手入門 ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings MediaWiki 系統設定]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki 常見問答集]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki 發佈郵寄清單]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources MediaWiki 介面在地化]"
 }
index ca5d534..f39f8fd 100644 (file)
@@ -42,6 +42,10 @@ class DeleteLinksJob extends Job {
                }
 
                $pageId = $this->params['pageId'];
+
+               // Serialize links updates by page ID so they see each others' changes
+               $scopedLock = LinksUpdate::acquirePageLock( wfGetDB( DB_MASTER ), $pageId, 'job' );
+
                if ( WikiPage::newFromID( $pageId, WikiPage::READ_LATEST ) ) {
                        // The page was restored somehow or something went wrong
                        $this->setLastError( "deleteLinks: Page #$pageId exists" );
index 8870569..8fba728 100644 (file)
@@ -128,7 +128,18 @@ class RefreshLinksJob extends Job {
         * @return bool
         */
        protected function runForTitle( Title $title ) {
+               $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+
                $page = WikiPage::factory( $title );
+               $page->loadPageData( WikiPage::READ_LATEST );
+
+               // Serialize links updates by page ID so they see each others' changes
+               $scopedLock = LinksUpdate::acquirePageLock( wfGetDB( DB_MASTER ), $page->getId(), 'job' );
+               // Get the latest ID *after* acquirePageLock() flushed the transaction.
+               // This is used to detect edits/moves after loadPageData() but before the scope lock.
+               // The works around the chicken/egg problem of determining the scope lock key.
+               $latest = $title->getLatestRevID( Title::GAID_FOR_UPDATE );
+
                if ( !empty( $this->params['triggeringRevisionId'] ) ) {
                        // Fetch the specified revision; lockAndGetLatest() below detects if the page
                        // was edited since and aborts in order to avoid corrupting the link tables
@@ -141,15 +152,15 @@ class RefreshLinksJob extends Job {
                        $revision = Revision::newFromTitle( $title, false, Revision::READ_LATEST );
                }
 
-               $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
-
                if ( !$revision ) {
                        $stats->increment( 'refreshlinks.rev_not_found' );
                        $this->setLastError( "Revision not found for {$title->getPrefixedDBkey()}" );
                        return false; // just deleted?
-               } elseif ( !$revision->isCurrent() ) {
-                       // If the revision isn't current, there's no point in doing a bunch
-                       // of work just to fail at the lockAndGetLatest() check later.
+               } elseif ( $revision->getId() != $latest || $revision->getPage() !== $page->getId() ) {
+                       // Do not clobber over newer updates with older ones. If all jobs where FIFO and
+                       // serialized, it would be OK to update links based on older revisions since it
+                       // would eventually get to the latest. Since that is not the case (by design),
+                       // only update the link tables to a state matching the current revision's output.
                        $stats->increment( 'refreshlinks.rev_not_current' );
                        $this->setLastError( "Revision {$revision->getId()} is not current" );
                        return false;
@@ -249,17 +260,6 @@ class RefreshLinksJob extends Job {
                        }
                }
 
-               $latestNow = $page->lockAndGetLatest();
-               if ( !$latestNow || $revision->getId() != $latestNow ) {
-                       // Do not clobber over newer updates with older ones. If all jobs where FIFO and
-                       // serialized, it would be OK to update links based on older revisions since it
-                       // would eventually get to the latest. Since that is not the case (by design),
-                       // only update the link tables to a state matching the current revision's output.
-                       $stats->increment( 'refreshlinks.rev_cas_failure' );
-                       $this->setLastError( "page_latest changed from {$revision->getId()} to $latestNow" );
-                       return false;
-               }
-
                DataUpdate::runUpdates( $updates );
 
                InfoAction::invalidateCache( $title );
index 0371f24..320a0b6 100644 (file)
@@ -35,6 +35,8 @@
  *                use application/x-www-form-urlencoded (headers sent automatically)
  *   - stream   : resource to stream the HTTP response body to
  *   - proxy    : HTTP proxy to use
+ *   - flags    : map of boolean flags which supports:
+ *                  - relayResponseHeaders : write out header via header()
  * Request maps can use integer index 0 instead of 'method' and 1 instead of 'url'.
  *
  * @author Aaron Schulz
@@ -172,6 +174,7 @@ class MultiHttpClient {
                                $req['body'] = '';
                                $req['headers']['content-length'] = 0;
                        }
+                       $req['flags'] = isset( $req['flags'] ) ? $req['flags'] : [];
                        $handles[$index] = $this->getCurlHandle( $req, $opts );
                        if ( count( $reqs ) > 1 ) {
                                // https://github.com/guzzle/guzzle/issues/349
@@ -373,6 +376,9 @@ class MultiHttpClient {
 
                curl_setopt( $ch, CURLOPT_HEADERFUNCTION,
                        function ( $ch, $header ) use ( &$req ) {
+                               if ( !empty( $req['flags']['relayResponseHeaders'] ) ) {
+                                       header( $header );
+                               }
                                $length = strlen( $header );
                                $matches = [];
                                if ( preg_match( "/^(HTTP\/1\.[01]) (\d{3}) (.*)/", $header, $matches ) ) {
diff --git a/includes/libs/ReverseArrayIterator.php b/includes/libs/ReverseArrayIterator.php
new file mode 100644 (file)
index 0000000..37b68c3
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Convenience class for iterating over an array in reverse order.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.27
+ */
+
+/**
+ * Convenience class for iterating over an array in reverse order.
+ *
+ * @since 1.27
+ */
+class ReverseArrayIterator implements Iterator, Countable {
+       /** @var array $array */
+       protected $array;
+
+       /**
+        * Creates an iterator which will visit the keys in $array in
+        * reverse order.  If given an object, will visit the properties
+        * of the object in reverse order.  (Note that the default order
+        * for PHP arrays and objects is declaration/assignment order.)
+        *
+        * @param array|object $array
+        */
+       public function __construct( $array = [] ) {
+               if ( is_array( $array ) ) {
+                       $this->array = $array;
+               } elseif ( is_object( $array ) ) {
+                       $this->array = get_object_vars( $array );
+               } else {
+                       throw new InvalidArgumentException( __METHOD__ . ' requires an array or object' );
+               }
+
+               $this->rewind();
+       }
+
+        public function current() {
+               return current( $this->array );
+        }
+
+        public function key() {
+               return key( $this->array );
+        }
+
+        public function next() {
+               prev( $this->array );
+        }
+
+        public function rewind() {
+               end( $this->array );
+        }
+
+        public function valid() {
+               return key( $this->array ) !== null;
+        }
+
+        public function count() {
+               return count( $this->array );
+        }
+}
index 1bbfc56..9fc3fe1 100644 (file)
@@ -1,16 +1,24 @@
 <?php
 
 /**
- * Interface to key-value storage on HTTP RESTful server, such as RESTBase.
- * Uses URL of the form URL/{KEY} to store/fetch/delete.
- * E.g., when base URL is /v1/sessions/ then the store would do:
- * PUT /v1/sessions/12345758
+ * Interface to key-value storage behind an HTTP server.
+ *
+ * Uses URL of the form "baseURL/{KEY}" to store, fetch, and delete values.
+ *
+ * E.g., when base URL is `/v1/sessions/`, then the store would do:
+ *
+ * `PUT /v1/sessions/12345758`
+ *
  * and fetch would do:
- * GET /v1/sessions/12345758
+ *
+ * `GET /v1/sessions/12345758`
+ *
  * delete would do:
- * DELETE /v1/sessions/12345758
+ *
+ * `DELETE /v1/sessions/12345758`
  *
  * Configure with:
+ *
  * @code
  * $wgObjectCaches['sessions'] = array(
  *     'class' => 'RESTBagOStuff',
index 432dcb2..2d67b87 100644 (file)
@@ -25,8 +25,10 @@ use DummyLinker;
 use Hooks;
 use Html;
 use HtmlArmor;
+use LinkCache;
 use Linker;
 use MediaWiki\MediaWikiServices;
+use MWNamespace;
 use Sanitizer;
 use Title;
 use TitleFormatter;
@@ -62,6 +64,11 @@ class LinkRenderer {
         */
        private $titleFormatter;
 
+       /**
+        * @var LinkCache
+        */
+       private $linkCache;
+
        /**
         * Whether to run the legacy Linker hooks
         *
@@ -71,9 +78,11 @@ class LinkRenderer {
 
        /**
         * @param TitleFormatter $titleFormatter
+        * @param LinkCache $linkCache
         */
-       public function __construct( TitleFormatter $titleFormatter ) {
+       public function __construct( TitleFormatter $titleFormatter, LinkCache $linkCache ) {
                $this->titleFormatter = $titleFormatter;
+               $this->linkCache = $linkCache;
        }
 
        /**
@@ -225,7 +234,7 @@ class LinkRenderer {
        }
 
        /**
-        * If you have already looked up the proper CSS classes using Linker::getLinkColour()
+        * If you have already looked up the proper CSS classes using LinkRenderer::getLinkClasses()
         * or some other method, use this to avoid looking it up again.
         *
         * @param LinkTarget $target
@@ -276,7 +285,7 @@ class LinkRenderer {
                if ( $target->isExternal() ) {
                        $classes[] = 'extiw';
                }
-               $colour = Linker::getLinkColour( $target, $this->stubThreshold );
+               $colour = $this->getLinkClasses( $target );
                if ( $colour !== '' ) {
                        $classes[] = $colour;
                }
@@ -391,16 +400,13 @@ class LinkRenderer {
        private function getLinkURL( LinkTarget $target, array $query = [] ) {
                // TODO: Use a LinkTargetResolver service instead of Title
                $title = Title::newFromLinkTarget( $target );
-               $proto = $this->expandUrls !== false
-                       ? $this->expandUrls
-                       : PROTO_RELATIVE;
                if ( $this->forceArticlePath ) {
                        $realQuery = $query;
                        $query = [];
                } else {
                        $realQuery = [];
                }
-               $url = $title->getLinkURL( $query, false, $proto );
+               $url = $title->getLinkURL( $query, false, $this->expandUrls );
 
                if ( $this->forceArticlePath && $realQuery ) {
                        $url = wfAppendQuery( $url, $realQuery );
@@ -445,4 +451,30 @@ class LinkRenderer {
                return $ret;
        }
 
+       /**
+        * Return the CSS classes of a known link
+        *
+        * @param LinkTarget $target
+        * @return string CSS class
+        */
+       public function getLinkClasses( LinkTarget $target ) {
+               // Make sure the target is in the cache
+               $id = $this->linkCache->addLinkObj( $target );
+               if ( $id == 0 ) {
+                       // Doesn't exist
+                       return '';
+               }
+
+               if ( $this->linkCache->getGoodLinkFieldObj( $target, 'redirect' ) ) {
+                       # Page is a redirect
+                       return 'mw-redirect';
+               } elseif ( $this->stubThreshold > 0 && MWNamespace::isContent( $target->getNamespace() )
+                       && $this->linkCache->getGoodLinkFieldObj( $target, 'length' ) < $this->stubThreshold
+               ) {
+                       # Page is a stub
+                       return 'stub';
+               }
+
+               return '';
+       }
 }
index 7124be1..b7c05c2 100644 (file)
@@ -21,6 +21,7 @@
  */
 namespace MediaWiki\Linker;
 
+use LinkCache;
 use TitleFormatter;
 use User;
 
@@ -35,18 +36,25 @@ class LinkRendererFactory {
         */
        private $titleFormatter;
 
+       /**
+        * @var LinkCache
+        */
+       private $linkCache;
+
        /**
         * @param TitleFormatter $titleFormatter
+        * @param LinkCache $linkCache
         */
-       public function __construct( TitleFormatter $titleFormatter ) {
+       public function __construct( TitleFormatter $titleFormatter, LinkCache $linkCache ) {
                $this->titleFormatter = $titleFormatter;
+               $this->linkCache = $linkCache;
        }
 
        /**
         * @return LinkRenderer
         */
        public function create() {
-               return new LinkRenderer( $this->titleFormatter );
+               return new LinkRenderer( $this->titleFormatter, $this->linkCache );
        }
 
        /**
index 9176b54..b3a555a 100644 (file)
@@ -421,8 +421,10 @@ class ThumbnailImage extends MediaTransformOutput {
                }
 
                // Additional densities for responsive images, if specified.
-               if ( !empty( $this->responsiveUrls ) ) {
-                       $attribs['srcset'] = Html::srcSet( $this->responsiveUrls );
+               // If any of these urls is the same as src url, it'll be excluded.
+               $responsiveUrls = array_diff( $this->responsiveUrls, [ $this->url ] );
+               if ( !empty( $responsiveUrls ) ) {
+                       $attribs['srcset'] = Html::srcSet( $responsiveUrls );
                }
 
                Hooks::run( 'ThumbnailBeforeProduceHTML', [ $this, &$attribs, &$linkAttribs ] );
index b06b519..dbc27a9 100644 (file)
@@ -1103,15 +1103,10 @@ class WikiPage implements Page, IDBAccessObject {
                        return false;
                }
 
-               $title = $this->mTitle;
-               wfGetDB( DB_MASTER )->onTransactionIdle( function() use ( $title ) {
-                       // Invalidate the cache in auto-commit mode
-                       $title->invalidateCache();
-               } );
-
+               $this->mTitle->invalidateCache();
                // Send purge after above page_touched update was committed
                DeferredUpdates::addUpdate(
-                       new CdnCacheUpdate( $title->getCdnUrls() ),
+                       new CdnCacheUpdate( $this->mTitle->getCdnUrls() ),
                        DeferredUpdates::PRESEND
                );
 
@@ -3279,6 +3274,14 @@ class WikiPage implements Page, IDBAccessObject {
                $title->touchLinks();
                $title->purgeSquid();
                $title->deleteTitleProtection();
+
+               if ( $title->getNamespace() == NS_CATEGORY ) {
+                       // Load the Category object, which will schedule a job to create
+                       // the category table row if necessary. Checking a slave is ok
+                       // here, in the worst case it'll run an unnecessary recount job on
+                       // a category that probably doesn't have many members.
+                       Category::newFromTitle( $title )->getID();
+               }
        }
 
        /**
@@ -3525,6 +3528,22 @@ class WikiPage implements Page, IDBAccessObject {
                                        $cat = Category::newFromName( $catName );
                                        Hooks::run( 'CategoryAfterPageRemoved', [ $cat, $this, $id ] );
                                }
+
+                               // Refresh counts on categories that should be empty now, to
+                               // trigger possible deletion. Check master for the most
+                               // up-to-date cat_pages.
+                               if ( count( $deleted ) ) {
+                                       $rows = $dbw->select(
+                                               'category',
+                                               [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
+                                               [ 'cat_title' => $deleted, 'cat_pages <= 0' ],
+                                               $method
+                                       );
+                                       foreach ( $rows as $row ) {
+                                               $cat = Category::newFromRow( $row );
+                                               $cat->refreshCounts();
+                                       }
+                               }
                        }
                );
        }
index 1c6f404..b34ac1f 100644 (file)
@@ -288,7 +288,6 @@ class LinkHolderArray {
                $linkCache = LinkCache::singleton();
                $output = $this->parent->getOutput();
                $linkRenderer = $this->parent->getLinkRenderer();
-               $threshold = $linkRenderer->getStubThreshold();
 
                $dbr = wfGetDB( DB_SLAVE );
 
@@ -321,7 +320,7 @@ class LinkHolderArray {
                                } else {
                                        $id = $linkCache->getGoodLinkID( $pdbk );
                                        if ( $id != 0 ) {
-                                               $colours[$pdbk] = Linker::getLinkColour( $title, $threshold );
+                                               $colours[$pdbk] = $linkRenderer->getLinkClasses( $title );
                                                $output->addLink( $title, $id );
                                                $linkcolour_ids[$id] = $pdbk;
                                        } elseif ( $linkCache->isBadLink( $pdbk ) ) {
@@ -353,7 +352,7 @@ class LinkHolderArray {
                                $pdbk = $title->getPrefixedDBkey();
                                $linkCache->addGoodLinkObjFromRow( $title, $s );
                                $output->addLink( $title, $s->page_id );
-                               $colours[$pdbk] = Linker::getLinkColour( $title, $threshold );
+                               $colours[$pdbk] = $linkRenderer->getLinkClasses( $title );
                                // add id to the extension todolist
                                $linkcolour_ids[$s->page_id] = $pdbk;
                        }
@@ -456,7 +455,6 @@ class LinkHolderArray {
                $variantMap = []; // maps $pdbkey_Variant => $keys (of link holders)
                $output = $this->parent->getOutput();
                $linkCache = LinkCache::singleton();
-               $threshold = $this->parent->getOptions()->getStubThreshold();
                $titlesToBeConverted = '';
                $titlesAttrs = [];
 
@@ -549,6 +547,7 @@ class LinkHolderArray {
                        );
 
                        $linkcolour_ids = [];
+                       $linkRenderer = $this->parent->getLinkRenderer();
 
                        // for each found variants, figure out link holders and replace
                        foreach ( $varRes as $s ) {
@@ -575,7 +574,7 @@ class LinkHolderArray {
                                                $entry['pdbk'] = $varPdbk;
 
                                                // set pdbk and colour
-                                               $colours[$varPdbk] = Linker::getLinkColour( $variantTitle, $threshold );
+                                               $colours[$varPdbk] = $linkRenderer->getLinkClasses( $variantTitle );
                                                $linkcolour_ids[$s->page_id] = $pdbk;
                                        }
                                }
index bdf3efb..32d8373 100644 (file)
@@ -51,24 +51,6 @@ class MWTidy {
                return $driver->tidy( $text );
        }
 
-       /**
-        * Get CSS modules needed if HTML from the current driver is to be displayed.
-        *
-        * This is just a migration tool to allow some changes expected as part of
-        * Tidy replacement (T89331) to be exposed on the client side via user
-        * scripts, without actually replacing tidy. See T49673.
-        *
-        * @return array
-        */
-       public static function getModuleStyles() {
-               $driver = self::singleton();
-               if ( $driver && $driver instanceof MediaWiki\Tidy\RaggettBase ) {
-                       return [ 'mediawiki.raggett' ];
-               } else {
-                       return [];
-               }
-       }
-
        /**
         * Check HTML for errors, used if $wgValidateAllHtml = true.
         *
@@ -132,6 +114,11 @@ class MWTidy {
                                case 'Html5Depurate':
                                        self::$instance = new MediaWiki\Tidy\Html5Depurate( $config );
                                        break;
+                               case 'Html5Internal':
+                                       self::$instance = new MediaWiki\Tidy\Html5Internal( $config );
+                                       break;
+                               case 'disabled':
+                                       return false;
                                default:
                                        throw new MWException( "Invalid tidy driver: \"{$config['driver']}\"" );
                        }
index bd2f131..a765450 100644 (file)
@@ -1264,7 +1264,9 @@ class Parser {
                        $text,
                        [ &$this, 'attributeStripCallback' ],
                        false,
-                       array_keys( $this->mTransparentTagHooks )
+                       array_keys( $this->mTransparentTagHooks ),
+                       [],
+                       [ &$this, 'addTrackingCategory' ]
                );
                Hooks::run( 'InternalParseBeforeLinks', [ &$this, &$text, &$this->mStripState ] );
 
@@ -1355,7 +1357,6 @@ class Parser {
 
                if ( MWTidy::isEnabled() && $this->mOptions->getTidy() ) {
                        $text = MWTidy::tidy( $text );
-                       $this->mOutput->addModuleStyles( MWTidy::getModuleStyles() );
                } else {
                        # attempt to sanitize at least some nesting problems
                        # (bug #2702 and quite a few others)
index 0e11967..012288f 100644 (file)
  * Differences from DOM schema:
  *   * attribute nodes are children
  *   * "<h>" nodes that aren't at the top are replaced with <possible-h>
+ *
+ * Nodes are stored in a recursive array data structure. A node store is an
+ * array where each element may be either a scalar (representing a text node)
+ * or a "descriptor", which is a two-element array where the first element is
+ * the node name and the second element is the node store for the children.
+ *
+ * Attributes are represented as children that have a node name starting with
+ * "@", and a single text node child.
+ *
+ * @todo: Consider replacing descriptor arrays with objects of a new class.
+ * Benchmark and measure resulting memory impact.
+ *
  * @ingroup Parser
  */
 // @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
@@ -37,6 +49,7 @@ class Preprocessor_Hash extends Preprocessor {
        public $parser;
 
        const CACHE_PREFIX = 'preprocess-hash';
+       const CACHE_VERSION = 2;
 
        public function __construct( $parser ) {
                $this->parser = $parser;
@@ -65,23 +78,20 @@ class Preprocessor_Hash extends Preprocessor {
                $list = [];
 
                foreach ( $values as $k => $val ) {
-                       $partNode = new PPNode_Hash_Tree( 'part' );
-                       $nameNode = new PPNode_Hash_Tree( 'name' );
-
                        if ( is_int( $k ) ) {
-                               $nameNode->addChild( new PPNode_Hash_Attr( 'index', $k ) );
-                               $partNode->addChild( $nameNode );
+                               $store = [ [ 'part', [
+                                       [ 'name', [ [ '@index', [ $k ] ] ] ],
+                                       [ 'value', [ strval( $val ) ] ],
+                               ] ] ];
                        } else {
-                               $nameNode->addChild( new PPNode_Hash_Text( $k ) );
-                               $partNode->addChild( $nameNode );
-                               $partNode->addChild( new PPNode_Hash_Text( '=' ) );
+                               $store = [ [ 'part', [
+                                       [ 'name', [ strval( $k ) ] ],
+                                       '=',
+                                       [ 'value', [ strval( $val ) ] ],
+                               ] ] ];
                        }
 
-                       $valueNode = new PPNode_Hash_Tree( 'value' );
-                       $valueNode->addChild( new PPNode_Hash_Text( $val ) );
-                       $partNode->addChild( $valueNode );
-
-                       $list[] = $partNode;
+                       $list[] = new PPNode_Hash_Tree( $store, 0 );
                }
 
                $node = new PPNode_Hash_Array( $list );
@@ -90,7 +100,6 @@ class Preprocessor_Hash extends Preprocessor {
 
        /**
         * Preprocess some wikitext and return the document tree.
-        * This is the ghost of Parser::replace_variables().
         *
         * @param string $text The text to parse
         * @param int $flags Bitwise combination of:
@@ -104,17 +113,16 @@ class Preprocessor_Hash extends Preprocessor {
         * change in the DOM tree for a given text, must be passed through the section identifier
         * in the section edit link and thus back to extractSections().
         *
-        * The output of this function is currently only cached in process memory, but a persistent
-        * cache may be implemented at a later date which takes further advantage of these strict
-        * dependency requirements.
-        *
         * @throws MWException
         * @return PPNode_Hash_Tree
         */
        public function preprocessToObj( $text, $flags = 0 ) {
                $tree = $this->cacheGetTree( $text, $flags );
                if ( $tree !== false ) {
-                       return unserialize( $tree );
+                       $store = json_decode( $tree );
+                       if ( is_array( $store ) ) {
+                               return new PPNode_Hash_Tree( $store, 0 );
+                       }
                }
 
                $forInclusion = $flags & Parser::PTD_FOR_INCLUSION;
@@ -150,7 +158,7 @@ class Preprocessor_Hash extends Preprocessor {
 
                // Input pointer, starts out pointing to a pseudo-newline before the start
                $i = 0;
-               // Current accumulator
+               // Current accumulator. See the doc comment for Preprocessor_Hash for the format.
                $accum =& $stack->getAccum();
                // True to find equals signs in arguments
                $findEquals = false;
@@ -176,11 +184,11 @@ class Preprocessor_Hash extends Preprocessor {
                                $startPos = strpos( $text, '<onlyinclude>', $i );
                                if ( $startPos === false ) {
                                        // Ignored section runs to the end
-                                       $accum->addNodeWithText( 'ignore', substr( $text, $i ) );
+                                       $accum[] = [ 'ignore', [ substr( $text, $i ) ] ];
                                        break;
                                }
                                $tagEndPos = $startPos + strlen( '<onlyinclude>' ); // past-the-end
-                               $accum->addNodeWithText( 'ignore', substr( $text, $i, $tagEndPos - $i ) );
+                               $accum[] = [ 'ignore', [ substr( $text, $i, $tagEndPos - $i ) ] ];
                                $i = $tagEndPos;
                                $findOnlyinclude = false;
                        }
@@ -208,7 +216,7 @@ class Preprocessor_Hash extends Preprocessor {
                                # Output literal section, advance input counter
                                $literalLength = strcspn( $text, $search, $i );
                                if ( $literalLength > 0 ) {
-                                       $accum->addLiteral( substr( $text, $i, $literalLength ) );
+                                       self::addLiteral( $accum, substr( $text, $i, $literalLength ) );
                                        $i += $literalLength;
                                }
                                if ( $i >= $lengthText ) {
@@ -261,7 +269,7 @@ class Preprocessor_Hash extends Preprocessor {
                                // Determine element name
                                if ( !preg_match( $elementsRegex, $text, $matches, 0, $i + 1 ) ) {
                                        // Element name missing or not listed
-                                       $accum->addLiteral( '<' );
+                                       self::addLiteral( $accum, '<' );
                                        ++$i;
                                        continue;
                                }
@@ -278,7 +286,7 @@ class Preprocessor_Hash extends Preprocessor {
                                        if ( $endPos === false ) {
                                                // Unclosed comment in input, runs to end
                                                $inner = substr( $text, $i );
-                                               $accum->addNodeWithText( 'comment', $inner );
+                                               $accum[] = [ 'comment', [ $inner ] ];
                                                $i = $lengthText;
                                        } else {
                                                // Search backwards for leading whitespace
@@ -309,13 +317,16 @@ class Preprocessor_Hash extends Preprocessor {
                                                        && substr( $text, $wsEnd + 1, 1 ) == "\n"
                                                ) {
                                                        // Remove leading whitespace from the end of the accumulator
-                                                       // Sanity check first though
                                                        $wsLength = $i - $wsStart;
+                                                       $endIndex = count( $accum ) - 1;
+
+                                                       // Sanity check
                                                        if ( $wsLength > 0
-                                                               && $accum->lastNode instanceof PPNode_Hash_Text
-                                                               && strspn( $accum->lastNode->value, " \t", -$wsLength ) === $wsLength
+                                                               && $endIndex >= 0
+                                                               && is_string( $accum[$endIndex] )
+                                                               && strspn( $accum[$endIndex], " \t", -$wsLength ) === $wsLength
                                                        ) {
-                                                               $accum->lastNode->value = substr( $accum->lastNode->value, 0, -$wsLength );
+                                                               $accum[$endIndex] = substr( $accum[$endIndex], 0, -$wsLength );
                                                        }
 
                                                        // Dump all but the last comment to the accumulator
@@ -326,7 +337,7 @@ class Preprocessor_Hash extends Preprocessor {
                                                                        break;
                                                                }
                                                                $inner = substr( $text, $startPos, $endPos - $startPos );
-                                                               $accum->addNodeWithText( 'comment', $inner );
+                                                               $accum[] = [ 'comment', [ $inner ] ];
                                                        }
 
                                                        // Do a line-start run next time to look for headings after the comment
@@ -347,7 +358,7 @@ class Preprocessor_Hash extends Preprocessor {
                                                }
                                                $i = $endPos + 1;
                                                $inner = substr( $text, $startPos, $endPos - $startPos + 1 );
-                                               $accum->addNodeWithText( 'comment', $inner );
+                                               $accum[] = [ 'comment', [ $inner ] ];
                                        }
                                        continue;
                                }
@@ -361,14 +372,14 @@ class Preprocessor_Hash extends Preprocessor {
                                        // Infinite backtrack
                                        // Disable tag search to prevent worst-case O(N^2) performance
                                        $noMoreGT = true;
-                                       $accum->addLiteral( '<' );
+                                       self::addLiteral( $accum, '<' );
                                        ++$i;
                                        continue;
                                }
 
                                // Handle ignored tags
                                if ( in_array( $lowerName, $ignoredTags ) ) {
-                                       $accum->addNodeWithText( 'ignore', substr( $text, $i, $tagEndPos - $i + 1 ) );
+                                       $accum[] = [ 'ignore', [ substr( $text, $i, $tagEndPos - $i + 1 ) ] ];
                                        $i = $tagEndPos + 1;
                                        continue;
                                }
@@ -401,7 +412,8 @@ class Preprocessor_Hash extends Preprocessor {
                                                } else {
                                                        // Don't match the tag, treat opening tag as literal and resume parsing.
                                                        $i = $tagEndPos + 1;
-                                                       $accum->addLiteral( substr( $text, $tagStartPos, $tagEndPos + 1 - $tagStartPos ) );
+                                                       self::addLiteral( $accum,
+                                                               substr( $text, $tagStartPos, $tagEndPos + 1 - $tagStartPos ) );
                                                        // Cache results, otherwise we have O(N^2) performance for input like <foo><foo><foo>...
                                                        $noMoreClosingTag[$name] = true;
                                                        continue;
@@ -410,7 +422,7 @@ class Preprocessor_Hash extends Preprocessor {
                                }
                                // <includeonly> and <noinclude> just become <ignore> tags
                                if ( in_array( $lowerName, $ignoredElements ) ) {
-                                       $accum->addNodeWithText( 'ignore', substr( $text, $tagStartPos, $i - $tagStartPos ) );
+                                       $accum[] = [ 'ignore', [ substr( $text, $tagStartPos, $i - $tagStartPos ) ] ];
                                        continue;
                                }
 
@@ -422,23 +434,23 @@ class Preprocessor_Hash extends Preprocessor {
                                        $attr = substr( $text, $attrStart, $attrEnd - $attrStart );
                                }
 
-                               $extNode = new PPNode_Hash_Tree( 'ext' );
-                               $extNode->addChild( PPNode_Hash_Tree::newWithText( 'name', $name ) );
-                               $extNode->addChild( PPNode_Hash_Tree::newWithText( 'attr', $attr ) );
+                               $children = [
+                                       [ 'name', [ $name ] ],
+                                       [ 'attr', [ $attr ] ] ];
                                if ( $inner !== null ) {
-                                       $extNode->addChild( PPNode_Hash_Tree::newWithText( 'inner', $inner ) );
+                                       $children[] = [ 'inner', [ $inner ] ];
                                }
                                if ( $close !== null ) {
-                                       $extNode->addChild( PPNode_Hash_Tree::newWithText( 'close', $close ) );
+                                       $children[] = [ 'close', [ $close ] ];
                                }
-                               $accum->addNode( $extNode );
+                               $accum[] = [ 'ext', $children ];
                        } elseif ( $found == 'line-start' ) {
                                // Is this the start of a heading?
                                // Line break belongs before the heading element in any case
                                if ( $fakeLineStart ) {
                                        $fakeLineStart = false;
                                } else {
-                                       $accum->addLiteral( $curChar );
+                                       self::addLiteral( $accum, $curChar );
                                        $i++;
                                }
 
@@ -494,11 +506,15 @@ class Preprocessor_Hash extends Preprocessor {
                                        }
                                        if ( $count > 0 ) {
                                                // Normal match, output <h>
-                                               $element = new PPNode_Hash_Tree( 'possible-h' );
-                                               $element->addChild( new PPNode_Hash_Attr( 'level', $count ) );
-                                               $element->addChild( new PPNode_Hash_Attr( 'i', $headingIndex++ ) );
-                                               $element->lastChild->nextSibling = $accum->firstNode;
-                                               $element->lastChild = $accum->lastNode;
+                                               $element = [ [ 'possible-h',
+                                                       array_merge(
+                                                               [
+                                                                       [ '@level', [ $count ] ],
+                                                                       [ '@i', [ $headingIndex++ ] ]
+                                                               ],
+                                                               $accum
+                                                       )
+                                               ] ];
                                        } else {
                                                // Single equals sign on its own line, count=0
                                                $element = $accum;
@@ -513,11 +529,8 @@ class Preprocessor_Hash extends Preprocessor {
                                extract( $stack->getFlags() );
 
                                // Append the result to the enclosing accumulator
-                               if ( $element instanceof PPNode ) {
-                                       $accum->addNode( $element );
-                               } else {
-                                       $accum->addAccum( $element );
-                               }
+                               array_splice( $accum, count( $accum ), 0, $element );
+
                                // Note that we do NOT increment the input pointer.
                                // This is because the closing linebreak could be the opening linebreak of
                                // another heading. Infinite loops are avoided because the next iteration MUST
@@ -542,7 +555,7 @@ class Preprocessor_Hash extends Preprocessor {
                                        extract( $stack->getFlags() );
                                } else {
                                        # Add literal brace(s)
-                                       $accum->addLiteral( str_repeat( $curChar, $count ) );
+                                       self::addLiteral( $accum, str_repeat( $curChar, $count ) );
                                }
                                $i += $count;
                        } elseif ( $found == 'close' ) {
@@ -571,7 +584,7 @@ class Preprocessor_Hash extends Preprocessor {
                                if ( $matchingCount <= 0 ) {
                                        # No matching element found in callback array
                                        # Output a literal closing brace and continue
-                                       $accum->addLiteral( str_repeat( $curChar, $count ) );
+                                       self::addLiteral( $accum, str_repeat( $curChar, $count ) );
                                        $i += $count;
                                        continue;
                                }
@@ -579,77 +592,38 @@ class Preprocessor_Hash extends Preprocessor {
                                if ( $name === null ) {
                                        // No element, just literal text
                                        $element = $piece->breakSyntax( $matchingCount );
-                                       $element->addLiteral( str_repeat( $rule['end'], $matchingCount ) );
+                                       self::addLiteral( $element, str_repeat( $rule['end'], $matchingCount ) );
                                } else {
                                        # Create XML element
-                                       # Note: $parts is already XML, does not need to be encoded further
                                        $parts = $piece->parts;
                                        $titleAccum = $parts[0]->out;
                                        unset( $parts[0] );
 
-                                       $element = new PPNode_Hash_Tree( $name );
+                                       $children = [];
 
                                        # The invocation is at the start of the line if lineStart is set in
                                        # the stack, and all opening brackets are used up.
                                        if ( $maxCount == $matchingCount && !empty( $piece->lineStart ) ) {
-                                               $element->addChild( new PPNode_Hash_Attr( 'lineStart', 1 ) );
+                                               $children[] = [ '@lineStart', [ 1 ] ];
                                        }
-                                       $titleNode = new PPNode_Hash_Tree( 'title' );
-                                       $titleNode->firstChild = $titleAccum->firstNode;
-                                       $titleNode->lastChild = $titleAccum->lastNode;
-                                       $element->addChild( $titleNode );
+                                       $titleNode = [ 'title', $titleAccum ];
+                                       $children[] = $titleNode;
                                        $argIndex = 1;
                                        foreach ( $parts as $part ) {
                                                if ( isset( $part->eqpos ) ) {
-                                                       // Find equals
-                                                       $lastNode = false;
-                                                       for ( $node = $part->out->firstNode; $node; $node = $node->nextSibling ) {
-                                                               if ( $node === $part->eqpos ) {
-                                                                       break;
-                                                               }
-                                                               $lastNode = $node;
-                                                       }
-                                                       if ( !$node ) {
-                                                               // if ( $cacheable ) { ... }
-                                                               throw new MWException( __METHOD__ . ': eqpos not found' );
-                                                       }
-                                                       if ( $node->name !== 'equals' ) {
-                                                               // if ( $cacheable ) { ... }
-                                                               throw new MWException( __METHOD__ . ': eqpos is not equals' );
-                                                       }
-                                                       $equalsNode = $node;
-
-                                                       // Construct name node
-                                                       $nameNode = new PPNode_Hash_Tree( 'name' );
-                                                       if ( $lastNode !== false ) {
-                                                               $lastNode->nextSibling = false;
-                                                               $nameNode->firstChild = $part->out->firstNode;
-                                                               $nameNode->lastChild = $lastNode;
-                                                       }
-
-                                                       // Construct value node
-                                                       $valueNode = new PPNode_Hash_Tree( 'value' );
-                                                       if ( $equalsNode->nextSibling !== false ) {
-                                                               $valueNode->firstChild = $equalsNode->nextSibling;
-                                                               $valueNode->lastChild = $part->out->lastNode;
-                                                       }
-                                                       $partNode = new PPNode_Hash_Tree( 'part' );
-                                                       $partNode->addChild( $nameNode );
-                                                       $partNode->addChild( $equalsNode->firstChild );
-                                                       $partNode->addChild( $valueNode );
-                                                       $element->addChild( $partNode );
+                                                       $equalsNode = $part->out[$part->eqpos];
+                                                       $nameNode = [ 'name', array_slice( $part->out, 0, $part->eqpos ) ];
+                                                       $valueNode = [ 'value', array_slice( $part->out, $part->eqpos + 1 ) ];
+                                                       $partNode = [ 'part', [ $nameNode, $equalsNode, $valueNode ] ];
+                                                       $children[] = $partNode;
                                                } else {
-                                                       $partNode = new PPNode_Hash_Tree( 'part' );
-                                                       $nameNode = new PPNode_Hash_Tree( 'name' );
-                                                       $nameNode->addChild( new PPNode_Hash_Attr( 'index', $argIndex++ ) );
-                                                       $valueNode = new PPNode_Hash_Tree( 'value' );
-                                                       $valueNode->firstChild = $part->out->firstNode;
-                                                       $valueNode->lastChild = $part->out->lastNode;
-                                                       $partNode->addChild( $nameNode );
-                                                       $partNode->addChild( $valueNode );
-                                                       $element->addChild( $partNode );
+                                                       $nameNode = [ 'name', [ [ '@index', [ $argIndex++ ] ] ] ];
+                                                       $valueNode = [ 'value', $part->out ];
+                                                       $partNode = [ 'part', [ $nameNode, $valueNode ] ];
+                                                       $children[] = $partNode;
                                                }
                                        }
+                                       $element = [ [ $name, $children ] ];
                                }
 
                                # Advance input pointer
@@ -669,18 +643,14 @@ class Preprocessor_Hash extends Preprocessor {
                                                $stack->push( $piece );
                                                $accum =& $stack->getAccum();
                                        } else {
-                                               $accum->addLiteral( str_repeat( $piece->open, $piece->count ) );
+                                               self::addLiteral( $accum, str_repeat( $piece->open, $piece->count ) );
                                        }
                                }
 
                                extract( $stack->getFlags() );
 
                                # Add XML element to the enclosing accumulator
-                               if ( $element instanceof PPNode ) {
-                                       $accum->addNode( $element );
-                               } else {
-                                       $accum->addAccum( $element );
-                               }
+                               array_splice( $accum, count( $accum ), 0, $element );
                        } elseif ( $found == 'pipe' ) {
                                $findEquals = true; // shortcut for getFlags()
                                $stack->addPart();
@@ -688,33 +658,44 @@ class Preprocessor_Hash extends Preprocessor {
                                ++$i;
                        } elseif ( $found == 'equals' ) {
                                $findEquals = false; // shortcut for getFlags()
-                               $accum->addNodeWithText( 'equals', '=' );
-                               $stack->getCurrentPart()->eqpos = $accum->lastNode;
+                               $accum[] = [ 'equals', [ '=' ] ];
+                               $stack->getCurrentPart()->eqpos = count( $accum ) - 1;
                                ++$i;
                        }
                }
 
                # Output any remaining unclosed brackets
                foreach ( $stack->stack as $piece ) {
-                       $stack->rootAccum->addAccum( $piece->breakSyntax() );
+                       array_splice( $stack->rootAccum, count( $stack->rootAccum ), 0, $piece->breakSyntax() );
                }
 
                # Enable top-level headings
-               for ( $node = $stack->rootAccum->firstNode; $node; $node = $node->nextSibling ) {
-                       if ( isset( $node->name ) && $node->name === 'possible-h' ) {
-                               $node->name = 'h';
+               foreach ( $stack->rootAccum as &$node ) {
+                       if ( is_array( $node ) && $node[PPNode_Hash_Tree::NAME] === 'possible-h' ) {
+                               $node[PPNode_Hash_Tree::NAME] = 'h';
                        }
                }
 
-               $rootNode = new PPNode_Hash_Tree( 'root' );
-               $rootNode->firstChild = $stack->rootAccum->firstNode;
-               $rootNode->lastChild = $stack->rootAccum->lastNode;
+               $rootStore = [ [ 'root', $stack->rootAccum ] ];
+               $rootNode = new PPNode_Hash_Tree( $rootStore, 0 );
 
                // Cache
-               $this->cacheSetTree( $text, $flags, serialize( $rootNode ) );
+               $tree = json_encode( $rootStore, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
+               if ( $tree !== false ) {
+                       $this->cacheSetTree( $text, $flags, $tree );
+               }
 
                return $rootNode;
        }
+
+       private static function addLiteral( array &$accum, $text ) {
+               $n = count( $accum );
+               if ( $n && is_string( $accum[$n - 1] ) ) {
+                       $accum[$n - 1] .= $text;
+               } else {
+                       $accum[] = $text;
+               }
+       }
 }
 
 /**
@@ -728,7 +709,7 @@ class PPDStack_Hash extends PPDStack {
        public function __construct() {
                $this->elementClass = 'PPDStackElement_Hash';
                parent::__construct();
-               $this->rootAccum = new PPDAccum_Hash;
+               $this->rootAccum = [];
        }
 }
 
@@ -748,7 +729,7 @@ class PPDStackElement_Hash extends PPDStackElement {
         * Get the accumulator that would result if the close is not found.
         *
         * @param int|bool $openingCount
-        * @return PPDAccum_Hash
+        * @return array
         */
        public function breakSyntax( $openingCount = false ) {
                if ( $this->open == "\n" ) {
@@ -757,16 +738,24 @@ class PPDStackElement_Hash extends PPDStackElement {
                        if ( $openingCount === false ) {
                                $openingCount = $this->count;
                        }
-                       $accum = new PPDAccum_Hash;
-                       $accum->addLiteral( str_repeat( $this->open, $openingCount ) );
+                       $accum = [ str_repeat( $this->open, $openingCount ) ];
+                       $lastIndex = 0;
                        $first = true;
                        foreach ( $this->parts as $part ) {
                                if ( $first ) {
                                        $first = false;
+                               } elseif ( is_string( $accum[$lastIndex] ) ) {
+                                       $accum[$lastIndex] .= '|';
                                } else {
-                                       $accum->addLiteral( '|' );
+                                       $accum[++$lastIndex] = '|';
+                               }
+                               foreach ( $part->out as $node ) {
+                                       if ( is_string( $node ) && is_string( $accum[$lastIndex] ) ) {
+                                               $accum[$lastIndex] .= $node;
+                                       } else {
+                                               $accum[++$lastIndex] = $node;
+                                       }
                                }
-                               $accum->addAccum( $part->out );
                        }
                }
                return $accum;
@@ -781,81 +770,12 @@ class PPDPart_Hash extends PPDPart {
        // @codingStandardsIgnoreEnd
 
        public function __construct( $out = '' ) {
-               $accum = new PPDAccum_Hash;
                if ( $out !== '' ) {
-                       $accum->addLiteral( $out );
-               }
-               parent::__construct( $accum );
-       }
-}
-
-/**
- * @ingroup Parser
- */
-// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
-class PPDAccum_Hash {
-       // @codingStandardsIgnoreEnd
-
-       public $firstNode, $lastNode;
-
-       public function __construct() {
-               $this->firstNode = $this->lastNode = false;
-       }
-
-       /**
-        * Append a string literal
-        * @param string $s
-        */
-       public function addLiteral( $s ) {
-               if ( $this->lastNode === false ) {
-                       $this->firstNode = $this->lastNode = new PPNode_Hash_Text( $s );
-               } elseif ( $this->lastNode instanceof PPNode_Hash_Text ) {
-                       $this->lastNode->value .= $s;
-               } else {
-                       $this->lastNode->nextSibling = new PPNode_Hash_Text( $s );
-                       $this->lastNode = $this->lastNode->nextSibling;
-               }
-       }
-
-       /**
-        * Append a PPNode
-        * @param PPNode $node
-        */
-       public function addNode( PPNode $node ) {
-               if ( $this->lastNode === false ) {
-                       $this->firstNode = $this->lastNode = $node;
-               } else {
-                       $this->lastNode->nextSibling = $node;
-                       $this->lastNode = $node;
-               }
-       }
-
-       /**
-        * Append a tree node with text contents
-        * @param string $name
-        * @param string $value
-        */
-       public function addNodeWithText( $name, $value ) {
-               $node = PPNode_Hash_Tree::newWithText( $name, $value );
-               $this->addNode( $node );
-       }
-
-       /**
-        * Append a PPDAccum_Hash
-        * Takes over ownership of the nodes in the source argument. These nodes may
-        * subsequently be modified, especially nextSibling.
-        * @param PPDAccum_Hash $accum
-        */
-       public function addAccum( $accum ) {
-               if ( $accum->lastNode === false ) {
-                       // nothing to add
-               } elseif ( $this->lastNode === false ) {
-                       $this->firstNode = $accum->firstNode;
-                       $this->lastNode = $accum->lastNode;
+                       $accum = [ $out ];
                } else {
-                       $this->lastNode->nextSibling = $accum->firstNode;
-                       $this->lastNode = $accum->lastNode;
+                       $accum = [];
                }
+               parent::__construct( $accum );
        }
 }
 
@@ -1050,130 +970,144 @@ class PPFrame_Hash implements PPFrame {
                        }
 
                        $newIterator = false;
+                       $contextName = false;
+                       $contextChildren = false;
 
                        if ( $contextNode === false ) {
                                // nothing to do
                        } elseif ( is_string( $contextNode ) ) {
                                $out .= $contextNode;
-                       } elseif ( is_array( $contextNode ) || $contextNode instanceof PPNode_Hash_Array ) {
+                       } elseif ( $contextNode instanceof PPNode_Hash_Array ) {
                                $newIterator = $contextNode;
                        } elseif ( $contextNode instanceof PPNode_Hash_Attr ) {
                                // No output
                        } elseif ( $contextNode instanceof PPNode_Hash_Text ) {
                                $out .= $contextNode->value;
                        } elseif ( $contextNode instanceof PPNode_Hash_Tree ) {
-                               if ( $contextNode->name == 'template' ) {
-                                       # Double-brace expansion
-                                       $bits = $contextNode->splitTemplate();
-                                       if ( $flags & PPFrame::NO_TEMPLATES ) {
-                                               $newIterator = $this->virtualBracketedImplode(
-                                                       '{{', '|', '}}',
-                                                       $bits['title'],
-                                                       $bits['parts']
-                                               );
-                                       } else {
-                                               $ret = $this->parser->braceSubstitution( $bits, $this );
-                                               if ( isset( $ret['object'] ) ) {
-                                                       $newIterator = $ret['object'];
-                                               } else {
-                                                       $out .= $ret['text'];
-                                               }
-                                       }
-                               } elseif ( $contextNode->name == 'tplarg' ) {
-                                       # Triple-brace expansion
-                                       $bits = $contextNode->splitTemplate();
-                                       if ( $flags & PPFrame::NO_ARGS ) {
-                                               $newIterator = $this->virtualBracketedImplode(
-                                                       '{{{', '|', '}}}',
-                                                       $bits['title'],
-                                                       $bits['parts']
-                                               );
-                                       } else {
-                                               $ret = $this->parser->argSubstitution( $bits, $this );
-                                               if ( isset( $ret['object'] ) ) {
-                                                       $newIterator = $ret['object'];
-                                               } else {
-                                                       $out .= $ret['text'];
-                                               }
-                                       }
-                               } elseif ( $contextNode->name == 'comment' ) {
-                                       # HTML-style comment
-                                       # Remove it in HTML, pre+remove and STRIP_COMMENTS modes
-                                       # Not in RECOVER_COMMENTS mode (msgnw) though.
-                                       if ( ( $this->parser->ot['html']
-                                               || ( $this->parser->ot['pre'] && $this->parser->mOptions->getRemoveComments() )
-                                               || ( $flags & PPFrame::STRIP_COMMENTS )
-                                               ) && !( $flags & PPFrame::RECOVER_COMMENTS )
-                                       ) {
-                                               $out .= '';
-                                       } elseif ( $this->parser->ot['wiki'] && !( $flags & PPFrame::RECOVER_COMMENTS ) ) {
-                                               # Add a strip marker in PST mode so that pstPass2() can
-                                               # run some old-fashioned regexes on the result.
-                                               # Not in RECOVER_COMMENTS mode (extractSections) though.
-                                               $out .= $this->parser->insertStripItem( $contextNode->firstChild->value );
+                               $contextName = $contextNode->name;
+                               $contextChildren = $contextNode->getRawChildren();
+                       } elseif ( is_array( $contextNode ) ) {
+                               // Node descriptor array
+                               if ( count( $contextNode ) !== 2 ) {
+                                       throw new MWException( __METHOD__.
+                                               ': found an array where a node descriptor should be' );
+                               }
+                               list( $contextName, $contextChildren ) = $contextNode;
+                       } else {
+                               throw new MWException( __METHOD__ . ': Invalid parameter type' );
+                       }
+
+                       // Handle node descriptor array or tree object
+                       if ( $contextName === false ) {
+                               // Not a node, already handled above
+                       } elseif ( $contextName[0] === '@' ) {
+                               // Attribute: no output
+                       } elseif ( $contextName === 'template' ) {
+                               # Double-brace expansion
+                               $bits = PPNode_Hash_Tree::splitRawTemplate( $contextChildren );
+                               if ( $flags & PPFrame::NO_TEMPLATES ) {
+                                       $newIterator = $this->virtualBracketedImplode(
+                                               '{{', '|', '}}',
+                                               $bits['title'],
+                                               $bits['parts']
+                                       );
+                               } else {
+                                       $ret = $this->parser->braceSubstitution( $bits, $this );
+                                       if ( isset( $ret['object'] ) ) {
+                                               $newIterator = $ret['object'];
                                        } else {
-                                               # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
-                                               $out .= $contextNode->firstChild->value;
+                                               $out .= $ret['text'];
                                        }
-                               } elseif ( $contextNode->name == 'ignore' ) {
-                                       # Output suppression used by <includeonly> etc.
-                                       # OT_WIKI will only respect <ignore> in substed templates.
-                                       # The other output types respect it unless NO_IGNORE is set.
-                                       # extractSections() sets NO_IGNORE and so never respects it.
-                                       if ( ( !isset( $this->parent ) && $this->parser->ot['wiki'] )
-                                               || ( $flags & PPFrame::NO_IGNORE )
-                                       ) {
-                                               $out .= $contextNode->firstChild->value;
+                               }
+                       } elseif ( $contextName === 'tplarg' ) {
+                               # Triple-brace expansion
+                               $bits = PPNode_Hash_Tree::splitRawTemplate( $contextChildren );
+                               if ( $flags & PPFrame::NO_ARGS ) {
+                                       $newIterator = $this->virtualBracketedImplode(
+                                               '{{{', '|', '}}}',
+                                               $bits['title'],
+                                               $bits['parts']
+                                       );
+                               } else {
+                                       $ret = $this->parser->argSubstitution( $bits, $this );
+                                       if ( isset( $ret['object'] ) ) {
+                                               $newIterator = $ret['object'];
                                        } else {
-                                               // $out .= '';
+                                               $out .= $ret['text'];
                                        }
-                               } elseif ( $contextNode->name == 'ext' ) {
-                                       # Extension tag
-                                       $bits = $contextNode->splitExt() + [ 'attr' => null, 'inner' => null, 'close' => null ];
-                                       if ( $flags & PPFrame::NO_TAGS ) {
-                                               $s = '<' . $bits['name']->firstChild->value;
-                                               if ( $bits['attr'] ) {
-                                                       $s .= $bits['attr']->firstChild->value;
-                                               }
-                                               if ( $bits['inner'] ) {
-                                                       $s .= '>' . $bits['inner']->firstChild->value;
-                                                       if ( $bits['close'] ) {
-                                                               $s .= $bits['close']->firstChild->value;
-                                                       }
-                                               } else {
-                                                       $s .= '/>';
-                                               }
-                                               $out .= $s;
-                                       } else {
-                                               $out .= $this->parser->extensionSubstitution( $bits, $this );
+                               }
+                       } elseif ( $contextName === 'comment' ) {
+                               # HTML-style comment
+                               # Remove it in HTML, pre+remove and STRIP_COMMENTS modes
+                               # Not in RECOVER_COMMENTS mode (msgnw) though.
+                               if ( ( $this->parser->ot['html']
+                                       || ( $this->parser->ot['pre'] && $this->parser->mOptions->getRemoveComments() )
+                                       || ( $flags & PPFrame::STRIP_COMMENTS )
+                                       ) && !( $flags & PPFrame::RECOVER_COMMENTS )
+                               ) {
+                                       $out .= '';
+                               } elseif ( $this->parser->ot['wiki'] && !( $flags & PPFrame::RECOVER_COMMENTS ) ) {
+                                       # Add a strip marker in PST mode so that pstPass2() can
+                                       # run some old-fashioned regexes on the result.
+                                       # Not in RECOVER_COMMENTS mode (extractSections) though.
+                                       $out .= $this->parser->insertStripItem( $contextChildren[0] );
+                               } else {
+                                       # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
+                                       $out .= $contextChildren[0];
+                               }
+                       } elseif ( $contextName === 'ignore' ) {
+                               # Output suppression used by <includeonly> etc.
+                               # OT_WIKI will only respect <ignore> in substed templates.
+                               # The other output types respect it unless NO_IGNORE is set.
+                               # extractSections() sets NO_IGNORE and so never respects it.
+                               if ( ( !isset( $this->parent ) && $this->parser->ot['wiki'] )
+                                       || ( $flags & PPFrame::NO_IGNORE )
+                               ) {
+                                       $out .= $contextChildren[0];
+                               } else {
+                                       // $out .= '';
+                               }
+                       } elseif ( $contextName === 'ext' ) {
+                               # Extension tag
+                               $bits = PPNode_Hash_Tree::splitRawExt( $contextChildren ) +
+                                       [ 'attr' => null, 'inner' => null, 'close' => null ];
+                               if ( $flags & PPFrame::NO_TAGS ) {
+                                       $s = '<' . $bits['name']->getFirstChild()->value;
+                                       if ( $bits['attr'] ) {
+                                               $s .= $bits['attr']->getFirstChild()->value;
                                        }
-                               } elseif ( $contextNode->name == 'h' ) {
-                                       # Heading
-                                       if ( $this->parser->ot['html'] ) {
-                                               # Expand immediately and insert heading index marker
-                                               $s = '';
-                                               for ( $node = $contextNode->firstChild; $node; $node = $node->nextSibling ) {
-                                                       $s .= $this->expand( $node, $flags );
+                                       if ( $bits['inner'] ) {
+                                               $s .= '>' . $bits['inner']->getFirstChild()->value;
+                                               if ( $bits['close'] ) {
+                                                       $s .= $bits['close']->getFirstChild()->value;
                                                }
-
-                                               $bits = $contextNode->splitHeading();
-                                               $titleText = $this->title->getPrefixedDBkey();
-                                               $this->parser->mHeadings[] = [ $titleText, $bits['i'] ];
-                                               $serial = count( $this->parser->mHeadings ) - 1;
-                                               $marker = Parser::MARKER_PREFIX . "-h-$serial-" . Parser::MARKER_SUFFIX;
-                                               $s = substr( $s, 0, $bits['level'] ) . $marker . substr( $s, $bits['level'] );
-                                               $this->parser->mStripState->addGeneral( $marker, '' );
-                                               $out .= $s;
                                        } else {
-                                               # Expand in virtual stack
-                                               $newIterator = $contextNode->getChildren();
+                                               $s .= '/>';
                                        }
+                                       $out .= $s;
+                               } else {
+                                       $out .= $this->parser->extensionSubstitution( $bits, $this );
+                               }
+                       } elseif ( $contextName === 'h' ) {
+                               # Heading
+                               if ( $this->parser->ot['html'] ) {
+                                       # Expand immediately and insert heading index marker
+                                       $s = $this->expand( $contextChildren, $flags );
+                                       $bits = PPNode_Hash_Tree::splitRawHeading( $contextChildren );
+                                       $titleText = $this->title->getPrefixedDBkey();
+                                       $this->parser->mHeadings[] = [ $titleText, $bits['i'] ];
+                                       $serial = count( $this->parser->mHeadings ) - 1;
+                                       $marker = Parser::MARKER_PREFIX . "-h-$serial-" . Parser::MARKER_SUFFIX;
+                                       $s = substr( $s, 0, $bits['level'] ) . $marker . substr( $s, $bits['level'] );
+                                       $this->parser->mStripState->addGeneral( $marker, '' );
+                                       $out .= $s;
                                } else {
-                                       # Generic recursive expansion
-                                       $newIterator = $contextNode->getChildren();
+                                       # Expand in virtual stack
+                                       $newIterator = $contextChildren;
                                }
                        } else {
-                               throw new MWException( __METHOD__ . ': Invalid parameter type' );
+                               # Generic recursive expansion
+                               $newIterator = $contextChildren;
                        }
 
                        if ( $newIterator !== false ) {
@@ -1689,17 +1623,85 @@ class PPCustomFrame_Hash extends PPFrame_Hash {
 class PPNode_Hash_Tree implements PPNode {
        // @codingStandardsIgnoreEnd
 
-       public $name, $firstChild, $lastChild, $nextSibling;
+       public $name;
+
+       /**
+        * The store array for children of this node. It is "raw" in the sense that
+        * nodes are two-element arrays ("descriptors") rather than PPNode_Hash_*
+        * objects.
+        */
+       private $rawChildren;
+
+       /**
+        * The store array for the siblings of this node, including this node itself.
+        */
+       private $store;
+
+       /**
+        * The index into $this->store which contains the descriptor of this node.
+        */
+       private $index;
+
+       /**
+        * The offset of the name within descriptors, used in some places for
+        * readability.
+        */
+       const NAME = 0;
+
+       /**
+        * The offset of the child list within descriptors, used in some places for
+        * readability.
+        */
+       const CHILDREN = 1;
+
+       /**
+        * Construct an object using the data from $store[$index]. The rest of the
+        * store array can be accessed via getNextSibling().
+        *
+        * @param array $store
+        * @param integer $index
+        */
+       public function __construct( array $store, $index ) {
+               $this->store = $store;
+               $this->index = $index;
+               list( $this->name, $this->rawChildren ) = $this->store[$index];
+       }
+
+       /**
+        * Construct an appropriate PPNode_Hash_* object with a class that depends
+        * on what is at the relevant store index.
+        *
+        * @param array $store
+        * @param integer $index
+        * @return PPNode_Hash_Tree|PPNode_Hash_Attr|PPNode_Hash_Text
+        */
+       public static function factory( array $store, $index ) {
+               if ( !isset( $store[$index] ) ) {
+                       return false;
+               }
 
-       public function __construct( $name ) {
-               $this->name = $name;
-               $this->firstChild = $this->lastChild = $this->nextSibling = false;
+               $descriptor = $store[$index];
+               if ( is_string( $descriptor ) ) {
+                       $class = 'PPNode_Hash_Text';
+               } elseif ( is_array( $descriptor ) ) {
+                       if ( $descriptor[self::NAME][0] === '@' ) {
+                               $class = 'PPNode_Hash_Attr';
+                       } else {
+                               $class = 'PPNode_Hash_Tree';
+                       }
+               } else {
+                       throw new MWException( __METHOD__.': invalid node descriptor' );
+               }
+               return new $class( $store, $index );
        }
 
+       /**
+        * Convert a node to XML, for debugging
+        */
        public function __toString() {
                $inner = '';
                $attribs = '';
-               for ( $node = $this->firstChild; $node; $node = $node->nextSibling ) {
+               for ( $node = $this->getFirstChild(); $node; $node = $node->getNextSibling() ) {
                        if ( $node instanceof PPNode_Hash_Attr ) {
                                $attribs .= ' ' . $node->name . '="' . htmlspecialchars( $node->value ) . '"';
                        } else {
@@ -1713,55 +1715,67 @@ class PPNode_Hash_Tree implements PPNode {
                }
        }
 
-       /**
-        * @param string $name
-        * @param string $text
-        * @return PPNode_Hash_Tree
-        */
-       public static function newWithText( $name, $text ) {
-               $obj = new self( $name );
-               $obj->addChild( new PPNode_Hash_Text( $text ) );
-               return $obj;
-       }
-
-       public function addChild( $node ) {
-               if ( $this->lastChild === false ) {
-                       $this->firstChild = $this->lastChild = $node;
-               } else {
-                       $this->lastChild->nextSibling = $node;
-                       $this->lastChild = $node;
-               }
-       }
-
        /**
         * @return PPNode_Hash_Array
         */
        public function getChildren() {
                $children = [];
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       $children[] = $child;
+               foreach ( $this->rawChildren as $i => $child ) {
+                       $children[] = self::factory( $this->rawChildren, $i );
                }
                return new PPNode_Hash_Array( $children );
        }
 
+       /**
+        * Get the first child, or false if there is none. Note that this will
+        * return a temporary proxy object: different instances will be returned
+        * if this is called more than once on the same node.
+        *
+        * @return PPNode_Hash_Tree|PPNode_Hash_Attr|PPNode_Hash_Text|boolean
+        */
        public function getFirstChild() {
-               return $this->firstChild;
+               if ( !isset( $this->rawChildren[0] ) ) {
+                       return false;
+               } else {
+                       return self::factory( $this->rawChildren, 0 );
+               }
        }
 
+       /**
+        * Get the next sibling, or false if there is none. Note that this will
+        * return a temporary proxy object: different instances will be returned
+        * if this is called more than once on the same node.
+        *
+        * @return PPNode_Hash_Tree|PPNode_Hash_Attr|PPNode_Hash_Text|boolean
+        */
        public function getNextSibling() {
-               return $this->nextSibling;
+               return self::factory( $this->store, $this->index + 1 );
        }
 
+       /**
+        * Get an array of the children with a given node name
+        *
+        * @param string $name
+        * @return PPNode_Hash_Array
+        */
        public function getChildrenOfType( $name ) {
                $children = [];
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( isset( $child->name ) && $child->name === $name ) {
-                               $children[] = $child;
+               foreach ( $this->rawChildren as $i => $child ) {
+                       if ( is_array( $child ) && $child[self::NAME] === $name ) {
+                               $children[] = self::factory( $this->rawChildren, $i );
                        }
                }
                return new PPNode_Hash_Array( $children );
        }
 
+       /**
+        * Get the raw child array. For internal use.
+        * @return array
+        */
+       public function getRawChildren() {
+               return $this->rawChildren;
+       }
+
        /**
         * @return bool
         */
@@ -1794,20 +1808,27 @@ class PPNode_Hash_Tree implements PPNode {
         * @return array
         */
        public function splitArg() {
+               return self::splitRawArg( $this->rawChildren );
+       }
+
+       /**
+        * Like splitArg() but for a raw child array. For internal use only.
+        */
+       public static function splitRawArg( array $children ) {
                $bits = [];
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
+               foreach ( $children as $i => $child ) {
+                       if ( !is_array( $child ) ) {
                                continue;
                        }
-                       if ( $child->name === 'name' ) {
-                               $bits['name'] = $child;
-                               if ( $child->firstChild instanceof PPNode_Hash_Attr
-                                       && $child->firstChild->name === 'index'
+                       if ( $child[self::NAME] === 'name' ) {
+                               $bits['name'] = new self( $children, $i );
+                               if ( isset( $child[self::CHILDREN][0][self::NAME] )
+                                       && $child[self::CHILDREN][0][self::NAME] === '@index'
                                ) {
-                                       $bits['index'] = $child->firstChild->value;
+                                       $bits['index'] = $child[self::CHILDREN][0][self::CHILDREN][0];
                                }
-                       } elseif ( $child->name === 'value' ) {
-                               $bits['value'] = $child;
+                       } elseif ( $child[self::NAME] === 'value' ) {
+                               $bits['value'] = new self( $children, $i );
                        }
                }
 
@@ -1828,19 +1849,31 @@ class PPNode_Hash_Tree implements PPNode {
         * @return array
         */
        public function splitExt() {
+               return self::splitRawExt( $this->rawChildren );
+       }
+
+       /**
+        * Like splitExt() but for a raw child array. For internal use only.
+        */
+       public static function splitRawExt( array $children ) {
                $bits = [];
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
+               foreach ( $children as $i => $child ) {
+                       if ( !is_array( $child ) ) {
                                continue;
                        }
-                       if ( $child->name == 'name' ) {
-                               $bits['name'] = $child;
-                       } elseif ( $child->name == 'attr' ) {
-                               $bits['attr'] = $child;
-                       } elseif ( $child->name == 'inner' ) {
-                               $bits['inner'] = $child;
-                       } elseif ( $child->name == 'close' ) {
-                               $bits['close'] = $child;
+                       switch ( $child[self::NAME] ) {
+                       case 'name':
+                               $bits['name'] = new self( $children, $i );
+                               break;
+                       case 'attr':
+                               $bits['attr'] = new self( $children, $i );
+                               break;
+                       case 'inner':
+                               $bits['inner'] = new self( $children, $i );
+                               break;
+                       case 'close':
+                               $bits['close'] = new self( $children, $i );
+                               break;
                        }
                }
                if ( !isset( $bits['name'] ) ) {
@@ -1859,15 +1892,22 @@ class PPNode_Hash_Tree implements PPNode {
                if ( $this->name !== 'h' ) {
                        throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
                }
+               return self::splitRawHeading( $this->rawChildren );
+       }
+
+       /**
+        * Like splitHeading() but for a raw child array. For internal use only.
+        */
+       public static function splitRawHeading( array $children ) {
                $bits = [];
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
+               foreach ( $children as $i => $child ) {
+                       if ( !is_array( $child ) ) {
                                continue;
                        }
-                       if ( $child->name == 'i' ) {
-                               $bits['i'] = $child->value;
-                       } elseif ( $child->name == 'level' ) {
-                               $bits['level'] = $child->value;
+                       if ( $child[self::NAME] === '@i' ) {
+                               $bits['i'] = $child[self::CHILDREN][0];
+                       } elseif ( $child[self::NAME] === '@level' ) {
+                               $bits['level'] = $child[self::CHILDREN][0];
                        }
                }
                if ( !isset( $bits['i'] ) ) {
@@ -1883,20 +1923,29 @@ class PPNode_Hash_Tree implements PPNode {
         * @return array
         */
        public function splitTemplate() {
+               return self::splitRawTemplate( $this->rawChildren );
+       }
+
+       /**
+        * Like splitTemplate() but for a raw child array. For internal use only.
+        */
+       public static function splitRawTemplate( array $children ) {
                $parts = [];
                $bits = [ 'lineStart' => '' ];
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
+               foreach ( $children as $i => $child ) {
+                       if ( !is_array( $child ) ) {
                                continue;
                        }
-                       if ( $child->name == 'title' ) {
-                               $bits['title'] = $child;
-                       }
-                       if ( $child->name == 'part' ) {
-                               $parts[] = $child;
-                       }
-                       if ( $child->name == 'lineStart' ) {
+                       switch ( $child[self::NAME] ) {
+                       case 'title':
+                               $bits['title'] = new self( $children, $i );
+                               break;
+                       case 'part':
+                               $parts[] = new self( $children, $i );
+                               break;
+                       case '@lineStart':
                                $bits['lineStart'] = '1';
+                               break;
                        }
                }
                if ( !isset( $bits['title'] ) ) {
@@ -1914,13 +1963,23 @@ class PPNode_Hash_Tree implements PPNode {
 class PPNode_Hash_Text implements PPNode {
        // @codingStandardsIgnoreEnd
 
-       public $value, $nextSibling;
+       public $value;
+       private $store, $index;
 
-       public function __construct( $value ) {
-               if ( is_object( $value ) ) {
+       /**
+        * Construct an object using the data from $store[$index]. The rest of the
+        * store array can be accessed via getNextSibling().
+        *
+        * @param array $store
+        * @param integer $index
+        */
+       public function __construct( array $store, $index ) {
+               $this->value = $store[$index];
+               if ( !is_scalar( $this->value ) ) {
                        throw new MWException( __CLASS__ . ' given object instead of string' );
                }
-               $this->value = $value;
+               $this->store = $store;
+               $this->index = $index;
        }
 
        public function __toString() {
@@ -1928,7 +1987,7 @@ class PPNode_Hash_Text implements PPNode {
        }
 
        public function getNextSibling() {
-               return $this->nextSibling;
+               return PPNode_Hash_Tree::factory( $this->store, $this->index + 1 );
        }
 
        public function getChildren() {
@@ -1975,7 +2034,7 @@ class PPNode_Hash_Text implements PPNode {
 class PPNode_Hash_Array implements PPNode {
        // @codingStandardsIgnoreEnd
 
-       public $value, $nextSibling;
+       public $value;
 
        public function __construct( $value ) {
                $this->value = $value;
@@ -1998,7 +2057,7 @@ class PPNode_Hash_Array implements PPNode {
        }
 
        public function getNextSibling() {
-               return $this->nextSibling;
+               return false;
        }
 
        public function getChildren() {
@@ -2033,11 +2092,25 @@ class PPNode_Hash_Array implements PPNode {
 class PPNode_Hash_Attr implements PPNode {
        // @codingStandardsIgnoreEnd
 
-       public $name, $value, $nextSibling;
+       public $name, $value;
+       private $store, $index;
 
-       public function __construct( $name, $value ) {
-               $this->name = $name;
-               $this->value = $value;
+       /**
+        * Construct an object using the data from $store[$index]. The rest of the
+        * store array can be accessed via getNextSibling().
+        *
+        * @param array $store
+        * @param integer $index
+        */
+       public function __construct( array $store, $index ) {
+               $descriptor = $store[$index];
+               if ( $descriptor[PPNode_Hash_Tree::NAME][0] !== '@' ) {
+                       throw new MWException( __METHOD__.': invalid name in attribute descriptor' );
+               }
+               $this->name = substr( $descriptor[PPNode_Hash_Tree::NAME], 1 );
+               $this->value = $descriptor[PPNode_Hash_Tree::CHILDREN][0];
+               $this->store = $store;
+               $this->index = $index;
        }
 
        public function __toString() {
@@ -2049,7 +2122,7 @@ class PPNode_Hash_Attr implements PPNode {
        }
 
        public function getNextSibling() {
-               return $this->nextSibling;
+               return PPNode_Hash_Tree::factory( $this->store, $this->index + 1 );
        }
 
        public function getChildren() {
index 3fe9cdd..1017e44 100644 (file)
@@ -40,10 +40,6 @@ class ProfilerStub extends Profiler {
        public function close() {
        }
 
-       public function getCurrentSection() {
-               return '';
-       }
-
        public function logData() {
        }
 
index ea17990..12218ce 100644 (file)
@@ -109,6 +109,7 @@ class ExtensionProcessor implements Processor {
                'MessagesDirs',
                'type',
                'config',
+               'config_prefix',
                'ParserTestFiles',
                'AutoloadClasses',
                'manifest_version',
@@ -161,7 +162,12 @@ class ExtensionProcessor implements Processor {
         * @return array
         */
        public function extractInfo( $path, array $info, $version ) {
-               $this->extractConfig( $info );
+               if ( $version === 2 ) {
+                       $this->extractConfig2( $info );
+               } else {
+                       // $version === 1
+                       $this->extractConfig1( $info );
+               }
                $this->extractHooks( $info );
                $dir = dirname( $path );
                $this->extractExtensionMessagesFiles( $dir, $info );
@@ -349,12 +355,12 @@ class ExtensionProcessor implements Processor {
        }
 
        /**
-        * Set configuration settings
+        * Set configuration settings for manifest_version == 1
         * @todo In the future, this should be done via Config interfaces
         *
         * @param array $info
         */
-       protected function extractConfig( array $info ) {
+       protected function extractConfig1( array $info ) {
                if ( isset( $info['config'] ) ) {
                        if ( isset( $info['config']['_prefix'] ) ) {
                                $prefix = $info['config']['_prefix'];
@@ -370,6 +376,29 @@ class ExtensionProcessor implements Processor {
                }
        }
 
+       /**
+        * Set configuration settings for manifest_version == 2
+        * @todo In the future, this should be done via Config interfaces
+        *
+        * @param array $info
+        */
+       protected function extractConfig2( array $info ) {
+               if ( isset( $info['config_prefix'] ) ) {
+                       $prefix = $info['config_prefix'];
+               } else {
+                       $prefix = 'wg';
+               }
+               if ( isset( $info['config'] ) ) {
+                       foreach ( $info['config'] as $key => $data ) {
+                               $value = $data['value'];
+                               if ( isset( $value['merge_strategy'] ) ) {
+                                       $value[ExtensionRegistry::MERGE_STRATEGY] = $value['merge_strategy'];
+                               }
+                               $this->globals["$prefix$key"] = $value;
+                       }
+               }
+       }
+
        protected function extractParserTestFiles( $dir, array $info ) {
                if ( isset( $info['ParserTestFiles'] ) ) {
                        foreach ( $info['ParserTestFiles'] as $path ) {
index dc53ca4..3bec457 100644 (file)
@@ -19,7 +19,7 @@ class ExtensionRegistry {
        /**
         * Version of the highest supported manifest version
         */
-       const MANIFEST_VERSION = 1;
+       const MANIFEST_VERSION = 2;
 
        /**
         * Version of the oldest supported manifest version
index ccf764b..6596112 100644 (file)
@@ -1468,34 +1468,6 @@ MESSAGE;
                return wfAppendQuery( $script, $query );
        }
 
-       /**
-        * Build a load.php URL
-        * @deprecated since 1.24 Use createLoaderURL() instead
-        * @param array $modules Array of module names (strings)
-        * @param string $lang Language code
-        * @param string $skin Skin name
-        * @param string|null $user User name. If null, the &user= parameter is omitted
-        * @param string|null $version Versioning timestamp
-        * @param bool $debug Whether the request should be in debug mode
-        * @param string|null $only &only= parameter
-        * @param bool $printable Printable mode
-        * @param bool $handheld Handheld mode
-        * @param array $extraQuery Extra query parameters to add
-        * @return string URL to load.php. May be protocol-relative if $wgLoadScript is, too.
-        */
-       public static function makeLoaderURL( $modules, $lang, $skin, $user = null,
-               $version = null, $debug = false, $only = null, $printable = false,
-               $handheld = false, $extraQuery = []
-       ) {
-               global $wgLoadScript;
-
-               $query = self::makeLoaderQuery( $modules, $lang, $skin, $user, $version, $debug,
-                       $only, $printable, $handheld, $extraQuery
-               );
-
-               return wfAppendQuery( $wgLoadScript, $query );
-       }
-
        /**
         * Helper for createLoaderURL()
         *
@@ -1505,7 +1477,7 @@ MESSAGE;
         * @param array $extraQuery
         * @return array
         */
-       public static function createLoaderQuery( ResourceLoaderContext $context, $extraQuery = [] ) {
+       protected static function createLoaderQuery( ResourceLoaderContext $context, $extraQuery = [] ) {
                return self::makeLoaderQuery(
                        $context->getModules(),
                        $context->getLanguage(),
@@ -1522,7 +1494,7 @@ MESSAGE;
 
        /**
         * Build a query array (array representation of query string) for load.php. Helper
-        * function for makeLoaderURL().
+        * function for createLoaderURL().
         *
         * @param array $modules
         * @param string $lang
index b06553a..6b755d7 100644 (file)
@@ -922,6 +922,28 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                return $this->targets;
        }
 
+       /**
+        * Get the module's load type.
+        *
+        * @since 1.28
+        * @return string
+        */
+       public function getType() {
+               $canBeStylesOnly = !(
+                       // All options except 'styles', 'skinStyles' and 'debugRaw'
+                       $this->scripts
+                       || $this->debugScripts
+                       || $this->templates
+                       || $this->languageScripts
+                       || $this->skinScripts
+                       || $this->dependencies
+                       || $this->messages
+                       || $this->skipFunction
+                       || $this->raw
+               );
+               return $canBeStylesOnly ? self::LOAD_STYLES : self::LOAD_GENERAL;
+       }
+
        /**
         * Compile a LESS file into CSS.
         *
index 121a6c9..59f9a63 100644 (file)
@@ -35,6 +35,12 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
        const TYPE_STYLES = 'styles';
        const TYPE_COMBINED = 'combined';
 
+       # Desired load type
+       // Module only has styles (loaded via <style> or <link rel=stylesheet>)
+       const LOAD_STYLES = 'styles';
+       // Module may have other resources (loaded via mw.loader from a script)
+       const LOAD_GENERAL = 'general';
+
        # sitewide core module like a skin file or jQuery component
        const ORIGIN_CORE_SITEWIDE = 1;
 
@@ -343,6 +349,16 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                return $this->targets;
        }
 
+       /**
+        * Get the module's load type.
+        *
+        * @since 1.28
+        * @return string ResourceLoaderModule LOAD_* constant
+        */
+       public function getType() {
+               return self::LOAD_GENERAL;
+       }
+
        /**
         * Get the skip function.
         *
@@ -443,7 +459,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                                        ]
                                );
 
-                               $dbw->onTransactionIdle( function () use ( &$scopeLock ) {
+                               $dbw->onTransactionResolution( function () use ( &$scopeLock ) {
                                        ScopedCallback::consume( $scopeLock ); // release after commit
                                } );
                        }
index 6896ad7..46808a1 100644 (file)
@@ -43,4 +43,11 @@ class ResourceLoaderSiteStylesModule extends ResourceLoaderWikiModule {
                }
                return $pages;
        }
+
+       /**
+        * @return string
+        */
+       public function getType() {
+               return self::LOAD_STYLES;
+       }
 }
index 34866f3..7b2d532 100644 (file)
@@ -217,7 +217,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        }
 
                        $versionHash = $module->getVersionHash( $context );
-                       if ( strlen( $versionHash ) !== 8 ) {
+                       if ( strlen( $versionHash ) !== 7 ) {
                                $context->getLogger()->warning(
                                        "Module '{module}' produced an invalid version hash: '{version}'.",
                                        [
index 9c198d1..4d0bff7 100644 (file)
@@ -83,4 +83,11 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule {
        public function getGroup() {
                return 'private';
        }
+
+       /**
+        * @return string
+        */
+       public function getType() {
+               return self::LOAD_STYLES;
+       }
 }
index a3f8825..82051b1 100644 (file)
@@ -321,7 +321,21 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                return $this->titleInfo[$key];
        }
 
+       /**
+        * @return string
+        */
        public function getPosition() {
                return $this->position;
        }
+
+       /**
+        * @since 1.28
+        * @return string
+        */
+       public function getType() {
+               // Check both because subclasses don't always pass pages via the constructor,
+               // they may also override getPages() instead, in which case we should keep
+               // defaulting to LOAD_GENERAL and allow them to override getType() separately.
+               return ( $this->styles && !$this->scripts ) ? self::LOAD_STYLES : self::LOAD_GENERAL;
+       }
 }
index e2bb516..f47a70b 100644 (file)
@@ -107,8 +107,7 @@ class RevDelArchivedFileItem extends RevDelFileItem {
                                                'target' => $this->list->title->getPrefixedText(),
                                                'file' => $file->getKey(),
                                                'token' => $user->getEditToken( $file->getKey() )
-                                       ],
-                                       false, PROTO_RELATIVE
+                                       ]
                                ),
                        ];
                }
index 921fe5a..dca4d5a 100644 (file)
@@ -215,8 +215,7 @@ class RevDelFileItem extends RevDelItem {
                                                'target' => $this->list->title->getPrefixedText(),
                                                'file' => $file->getArchiveName(),
                                                'token' => $user->getEditToken( $file->getArchiveName() )
-                                       ],
-                                       false, PROTO_RELATIVE
+                                       ]
                                ),
                        ];
                }
index 0a86e94..3c81feb 100644 (file)
@@ -234,7 +234,7 @@ abstract class RevDelList extends RevisionListBase {
                }
 
                if ( $status->successCount == 0 ) {
-                       $dbw->rollback( __METHOD__ );
+                       $dbw->endAtomic( __METHOD__ );
                        return $status;
                }
 
@@ -244,8 +244,8 @@ abstract class RevDelList extends RevisionListBase {
                // Move files, if there are any
                $status->merge( $this->doPreCommitUpdates() );
                if ( !$status->isOK() ) {
-                       // Fatal error, such as no configured archive directory
-                       $dbw->rollback( __METHOD__ );
+                       // Fatal error, such as no configured archive directory or I/O failures
+                       wfGetLBFactory()->rollbackMasterChanges( __METHOD__ );
                        return $status;
                }
 
index 2ea255f..7499853 100644 (file)
@@ -22,7 +22,9 @@ interface SearchIndexField {
         */
        const FLAG_CASEFOLD = 1;
        /**
-        * This field is for scoring only.
+        * This field contains secondary information, which is
+        * already present in other fields, but can be used for
+        * scoring.
         */
        const FLAG_SCORING = 2;
        /**
@@ -30,7 +32,7 @@ interface SearchIndexField {
         */
        const FLAG_NO_HIGHLIGHT = 4;
        /**
-        * Do not index this field.
+        * Do not index this field, just store it.
         */
        const FLAG_NO_INDEX = 8;
        /**
index 3408db3..71ca57b 100644 (file)
@@ -140,7 +140,7 @@ abstract class BaseTemplate extends QuickTemplate {
                        if ( isset( $plink['active'] ) ) {
                                $ptool['active'] = $plink['active'];
                        }
-                       foreach ( [ 'href', 'class', 'text', 'dir' ] as $k ) {
+                       foreach ( [ 'href', 'class', 'text', 'dir', 'data' ] as $k ) {
                                if ( isset( $plink[$k] ) ) {
                                        $ptool['links'][0][$k] = $plink[$k];
                                }
@@ -318,6 +318,15 @@ abstract class BaseTemplate extends QuickTemplate {
         *
         * If you don't want an accesskey, set $item['tooltiponly'] = true;
         *
+        * If a "data" key is present, it must be an array, where the keys represent
+        * the data-xxx properties with their provided values. For example,
+        *  $item['data'] = array(
+        *       'foo' => 1,
+        *       'bar' => 'baz',
+        *  );
+        * will render as element properties:
+        *  data-foo='1' data-bar='baz'
+        *
         * @param array $options Can be used to affect the output of a link.
         * Possible options are:
         *   - 'text-wrapper' key to specify a list of elements to wrap the text of
@@ -363,6 +372,13 @@ abstract class BaseTemplate extends QuickTemplate {
                                unset( $attrs[$k] );
                        }
 
+                       if ( isset( $attrs['data'] ) ) {
+                               foreach ( $attrs['data'] as $key => $value ) {
+                                       $attrs[ 'data-' . $key ] = $value;
+                               }
+                               unset( $attrs[ 'data' ] );
+                       }
+
                        if ( isset( $item['id'] ) && !isset( $item['single-id'] ) ) {
                                $item['single-id'] = $item['id'];
                        }
@@ -425,7 +441,8 @@ abstract class BaseTemplate extends QuickTemplate {
         * list item directly so they will not be passed to makeLink
         * (however the link will still support a tooltip and accesskey from it)
         * If you need an id or class on a single link you should include a "links"
-        * array with just one link item inside of it. If you want to add a title
+        * array with just one link item inside of it. You can also set "link-class" in
+        * $item to set a class on the link itself. If you want to add a title
         * to the list item itself, you can set "itemtitle" to the value.
         * $options is also passed on to makeLink calls
         *
@@ -450,6 +467,12 @@ abstract class BaseTemplate extends QuickTemplate {
                                // generating tooltips and accesskeys.
                                $link['single-id'] = $item['id'];
                        }
+                       if ( isset( $link['link-class'] ) ) {
+                               // link-class should be set on the <a> itself,
+                               // so pass it in as 'class'
+                               $link['class'] = $link['link-class'];
+                               unset( $link['link-class'] );
+                       }
                        $html = $this->makeLink( $key, $link, $options );
                }
 
index 729f564..64d2f8b 100644 (file)
@@ -1241,6 +1241,8 @@ abstract class Skin extends ContextSource {
                $lines = explode( "\n", $text );
 
                $heading = '';
+               $messageTitle = $this->getConfig()->get( 'EnableSidebarCache' )
+                       ? Title::newMainPage() : $this->getTitle();
 
                foreach ( $lines as $line ) {
                        if ( strpos( $line, '*' ) !== 0 ) {
@@ -1257,7 +1259,7 @@ abstract class Skin extends ContextSource {
                                $line = trim( $line, '* ' );
 
                                if ( strpos( $line, '|' ) !== false ) { // sanity check
-                                       $line = MessageCache::singleton()->transform( $line, false, null, $this->getTitle() );
+                                       $line = MessageCache::singleton()->transform( $line, false, null, $messageTitle );
                                        $line = array_map( 'trim', explode( '|', $line, 2 ) );
                                        if ( count( $line ) !== 2 ) {
                                                // Second sanity check, could be hit by people doing
@@ -1267,7 +1269,7 @@ abstract class Skin extends ContextSource {
 
                                        $extraAttribs = [];
 
-                                       $msgLink = $this->msg( $line[0] )->inContentLanguage();
+                                       $msgLink = $this->msg( $line[0] )->title( $messageTitle )->inContentLanguage();
                                        if ( $msgLink->exists() ) {
                                                $link = $msgLink->text();
                                                if ( $link == '-' ) {
@@ -1276,7 +1278,7 @@ abstract class Skin extends ContextSource {
                                        } else {
                                                $link = $line[0];
                                        }
-                                       $msgText = $this->msg( $line[1] );
+                                       $msgText = $this->msg( $line[1] )->title( $messageTitle );
                                        if ( $msgText->exists() ) {
                                                $text = $msgText->text();
                                        } else {
index cefc5bc..69e2e8b 100644 (file)
@@ -17,6 +17,7 @@
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Base class for template-based skins.
@@ -749,6 +750,8 @@ class SkinTemplate extends Skin {
                        }
                }
 
+               $linkClass = MediaWikiServices::getInstance()->getLinkRenderer()->getLinkClasses( $title );
+
                // wfMessageFallback will nicely accept $message as an array of fallbacks
                // or just a single key
                $msg = wfMessageFallback( $message )->setContext( $this->getContext() );
@@ -771,11 +774,16 @@ class SkinTemplate extends Skin {
                        return $result;
                }
 
-               return [
+               $result = [
                        'class' => implode( ' ', $classes ),
                        'text' => $text,
                        'href' => $title->getLocalURL( $query ),
                        'primary' => true ];
+               if ( $linkClass !== '' ) {
+                       $result['link-class'] = $linkClass;
+               }
+
+               return $result;
        }
 
        function makeTalkUrlDetails( $name, $urlaction = '' ) {
index fcadede..ce7d24e 100644 (file)
@@ -645,8 +645,10 @@ class SpecialBlock extends FormSpecialPage {
                                return [ 'ipb-blockingself', 'ipb-confirmaction' ];
                        }
                } elseif ( $type == Block::TYPE_RANGE ) {
+                       $user = null;
                        $userId = 0;
                } elseif ( $type == Block::TYPE_IP ) {
+                       $user = null;
                        $target = $target->getName();
                        $userId = 0;
                } else {
@@ -729,6 +731,7 @@ class SpecialBlock extends FormSpecialPage {
                        return $reason;
                }
 
+               $priorBlock = null;
                # Try to insert block. Is there a conflicting block?
                $status = $block->insert();
                if ( !$status ) {
@@ -748,17 +751,16 @@ class SpecialBlock extends FormSpecialPage {
                                # This returns direct blocks before autoblocks/rangeblocks, since we should
                                # be sure the user is blocked by now it should work for our purposes
                                $currentBlock = Block::newFromTarget( $target );
-
                                if ( $block->equals( $currentBlock ) ) {
                                        return [ [ 'ipb_already_blocked', $block->getTarget() ] ];
                                }
-
                                # If the name was hidden and the blocking user cannot hide
                                # names, then don't allow any block changes...
                                if ( $currentBlock->mHideName && !$performer->isAllowed( 'hideuser' ) ) {
                                        return [ 'cant-see-hidden-user' ];
                                }
 
+                               $priorBlock = clone $currentBlock;
                                $currentBlock->isHardblock( $block->isHardblock() );
                                $currentBlock->prevents( 'createaccount', $block->prevents( 'createaccount' ) );
                                $currentBlock->mExpiry = $block->mExpiry;
@@ -786,7 +788,7 @@ class SpecialBlock extends FormSpecialPage {
                        $logaction = 'block';
                }
 
-               Hooks::run( 'BlockIpComplete', [ $block, $performer ] );
+               Hooks::run( 'BlockIpComplete', [ $block, $performer, $priorBlock ] );
 
                # Set *_deleted fields if requested
                if ( $data['HideUser'] ) {
index d01751e..f06a192 100644 (file)
@@ -129,7 +129,7 @@ class SpecialCreateAccount extends LoginSignupSpecialPage {
                # Run any hooks; display injected HTML
                $injected_html = '';
                $welcome_creation_msg = 'welcomecreation-msg';
-               Hooks::run( 'UserLoginComplete', [ &$user, &$injected_html ] );
+               Hooks::run( 'UserLoginComplete', [ &$user, &$injected_html, $direct ] );
 
                /**
                 * Let any extensions change what message is shown.
index af087a6..533a331 100644 (file)
@@ -37,6 +37,7 @@ class SpecialLog extends SpecialPage {
                $this->setHeaders();
                $this->outputHeader();
                $this->getOutput()->addModules( 'mediawiki.userSuggest' );
+               $this->addHelpLink( 'Help:Log' );
 
                $opts = new FormOptions;
                $opts->add( 'type', '' );
index 20a508d..d0c44c3 100644 (file)
@@ -139,8 +139,6 @@ class MovePageForm extends UnlistedSpecialPage {
         *    parameters, like the second argument to OutputPage::wrapWikiMsg().
         */
        function showForm( $err ) {
-               global $wgContLang;
-
                $this->getSkin()->setRelevantTitle( $this->oldTitle );
 
                $out = $this->getOutput();
@@ -316,7 +314,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                'title' => [
                                        'id' => 'wpNewTitleMain',
                                        'name' => 'wpNewTitleMain',
-                                       'value' => $wgContLang->recodeForEdit( $newTitle->getText() ),
+                                       'value' => $newTitle->getText(),
                                        // Inappropriate, since we're expecting the user to input a non-existent page's title
                                        'suggestions' => false,
                                ],
index f2eb88d..4c892b2 100644 (file)
@@ -53,6 +53,7 @@ class SpecialTrackingCategories extends SpecialPage {
                'node-count-exceeded-category',
                'expansion-depth-exceeded-category',
                'restricted-displaytitle-ignored',
+               'deprecated-self-close-category',
        ];
 
        function execute( $par ) {
index db20d87..21f5659 100644 (file)
@@ -124,7 +124,7 @@ class SpecialUserLogin extends LoginSignupSpecialPage {
 
                # Run any hooks; display injected HTML if any, else redirect
                $injected_html = '';
-               Hooks::run( 'UserLoginComplete', [ &$user, &$injected_html ] );
+               Hooks::run( 'UserLoginComplete', [ &$user, &$injected_html, $direct ] );
 
                if ( $injected_html !== '' || $extraMessages ) {
                        $this->showSuccessPage( 'success', $this->msg( 'loginsuccesstitle' ),
index fe0b4fe..f8eba9a 100644 (file)
@@ -224,6 +224,11 @@ class ContribsPager extends ReverseChronologicalPager {
                                        ]
                                ];
                        }
+                       // (T140537) Disallow looking too far in the past for 'newbies' queries. If the user requested
+                       // a timestamp offset far in the past such that there are no edits by users with user_ids in
+                       // the range, we would end up scanning all revisions from that offset until start of time.
+                       $condition[] = 'rev_timestamp > ' .
+                               $this->mDb->addQuotes( $this->mDb->timestamp( wfTimestamp() - 30 * 24 * 60 * 60 ) );
                } else {
                        $uid = User::idFromName( $this->target );
                        if ( $uid ) {
index 951cb52..09132f2 100644 (file)
@@ -1262,7 +1262,8 @@ class LoginFormPreAuthManager extends SpecialPage {
                # Run any hooks; display injected HTML if any, else redirect
                $currentUser = $this->getUser();
                $injected_html = '';
-               Hooks::run( 'UserLoginComplete', [ &$currentUser, &$injected_html ] );
+               $direct = RequestContext::getMain()->getRequest()->wasPosted();
+               Hooks::run( 'UserLoginComplete', [ &$currentUser, &$injected_html, $direct ] );
 
                if ( $injected_html !== '' ) {
                        $this->displaySuccessfulAction( 'success', $this->msg( 'loginsuccesstitle' ),
@@ -1283,8 +1284,9 @@ class LoginFormPreAuthManager extends SpecialPage {
                $currentUser = $this->getUser();
                $injected_html = '';
                $welcome_creation_msg = 'welcomecreation-msg';
+               $direct = RequestContext::getMain()->getRequest()->wasPosted();
 
-               Hooks::run( 'UserLoginComplete', [ &$currentUser, &$injected_html ] );
+               Hooks::run( 'UserLoginComplete', [ &$currentUser, &$injected_html, $direct ] );
 
                /**
                 * Let any extensions change what message is shown.
diff --git a/includes/tidy/Balancer.php b/includes/tidy/Balancer.php
new file mode 100644 (file)
index 0000000..b2d6ba1
--- /dev/null
@@ -0,0 +1,3535 @@
+<?php
+/**
+ * An implementation of the tree building portion of the HTML5 parsing
+ * spec.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Parser
+ * @since 1.27
+ * @author C. Scott Ananian, 2016
+ */
+namespace MediaWiki\Tidy;
+
+use Wikimedia\Assert\Assert;
+use Wikimedia\Assert\ParameterAssertionException;
+use \ExplodeIterator;
+use \IteratorAggregate;
+use \ReverseArrayIterator;
+use \Sanitizer;
+
+# A note for future librarization[1] -- this file is a good candidate
+# for splitting into an independent library, except that it is currently
+# highly optimized for MediaWiki use.  It only implements the portions
+# of the HTML5 tree builder used by tags supported by MediaWiki, and
+# does not contain a true tokenizer pass, instead relying on
+# comment stripping, attribute normalization, and escaping done by
+# the MediaWiki Sanitizer.  It also deliberately avoids building
+# a true DOM in memory, instead serializing elements to an output string
+# as soon as possible (usually as soon as the tag is closed) to reduce
+# its memory footprint.
+
+# We've been gradually lifting some of these restrictions to handle
+# non-sanitized output generated by extensions, but we shortcut the tokenizer
+# for speed (primarily by splitting on `<`) and so rely on syntactic
+# well-formedness.
+
+# On the other hand, I've been pretty careful to note with comments in the
+# code the places where this implementation omits features of the spec or
+# depends on the MediaWiki Sanitizer.  Perhaps in the future we'll want to
+# implement the missing pieces and make this a standalone PHP HTML5 parser.
+# In order to do so, some sort of MediaWiki-specific API will need
+# to be added to (a) allow the Balancer to bypass the tokenizer,
+# and (b) support on-the-fly flattening instead of DOM node creation.
+
+# [1]: https://www.mediawiki.org/wiki/Library_infrastructure_for_MediaWiki
+
+/**
+ * Utility constants and sets for the HTML5 tree building algorithm.
+ * Sets are associative arrays indexed first by namespace and then by
+ * lower-cased tag name.
+ *
+ * @ingroup Parser
+ * @since 1.27
+ */
+class BalanceSets {
+       const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
+       const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
+       const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
+
+       public static $unsupportedSet = [
+               self::HTML_NAMESPACE => [
+                       'html' => true, 'head' => true, 'body' => true, 'frameset' => true,
+                       'frame' => true,
+                       'plaintext' => true, 'isindex' => true,
+                       'xmp' => true, 'iframe' => true, 'noembed' => true,
+                       'noscript' => true, 'script' => true,
+                       'title' => true
+               ]
+       ];
+
+       public static $emptyElementSet = [
+               self::HTML_NAMESPACE => [
+                       'area' => true, 'base' => true, 'basefont' => true,
+                       'bgsound' => true, 'br' => true, 'col' => true, 'command' => true,
+                       'embed' => true, 'frame' => true, 'hr' => true, 'img' => true,
+                       'input' => true, 'keygen' => true, 'link' => true, 'meta' => true,
+                       'param' => true, 'source' => true, 'track' => true, 'wbr' => true
+               ]
+       ];
+
+       public static $extraLinefeedSet = [
+               self::HTML_NAMESPACE => [
+                       'pre' => true, 'textarea' => true, 'listing' => true,
+               ]
+       ];
+
+       public static $headingSet = [
+               self::HTML_NAMESPACE => [
+                       'h1' => true, 'h2' => true, 'h3' => true,
+                       'h4' => true, 'h5' => true, 'h6' => true
+               ]
+       ];
+
+       public static $specialSet = [
+               self::HTML_NAMESPACE => [
+                       'address' => true, 'applet' => true, 'area' => true,
+                       'article' => true, 'aside' => true, 'base' => true,
+                       'basefont' => true, 'bgsound' => true, 'blockquote' => true,
+                       'body' => true, 'br' => true, 'button' => true, 'caption' => true,
+                       'center' => true, 'col' => true, 'colgroup' => true, 'dd' => true,
+                       'details' => true, 'dir' => true, 'div' => true, 'dl' => true,
+                       'dt' => true, 'embed' => true, 'fieldset' => true,
+                       'figcaption' => true, 'figure' => true, 'footer' => true,
+                       'form' => true, 'frame' => true, 'frameset' => true, 'h1' => true,
+                       'h2' => true, 'h3' => true, 'h4' => true, 'h5' => true,
+                       'h6' => true, 'head' => true, 'header' => true, 'hgroup' => true,
+                       'hr' => true, 'html' => true, 'iframe' => true, 'img' => true,
+                       'input' => true, 'isindex' => true, 'li' => true, 'link' => true,
+                       'listing' => true, 'main' => true, 'marquee' => true,
+                       'menu' => true, 'menuitem' => true, 'meta' => true, 'nav' => true,
+                       'noembed' => true, 'noframes' => true, 'noscript' => true,
+                       'object' => true, 'ol' => true, 'p' => true, 'param' => true,
+                       'plaintext' => true, 'pre' => true, 'script' => true,
+                       'section' => true, 'select' => true, 'source' => true,
+                       'style' => true, 'summary' => true, 'table' => true,
+                       'tbody' => true, 'td' => true, 'template' => true,
+                       'textarea' => true, 'tfoot' => true, 'th' => true, 'thead' => true,
+                       'title' => true, 'tr' => true, 'track' => true, 'ul' => true,
+                       'wbr' => true, 'xmp' => true
+               ],
+               self::SVG_NAMESPACE => [
+                       'foreignobject' => true, 'desc' => true, 'title' => true
+               ],
+               self::MATHML_NAMESPACE => [
+                       'mi' => true, 'mo' => true, 'mn' => true, 'ms' => true,
+                       'mtext' => true, 'annotation-xml' => true
+               ]
+       ];
+
+       public static $addressDivPSet = [
+               self::HTML_NAMESPACE => [
+                       'address' => true, 'div' => true, 'p' => true
+               ]
+       ];
+
+       public static $tableSectionRowSet = [
+               self::HTML_NAMESPACE => [
+                       'table' => true, 'thead' => true, 'tbody' => true,
+                       'tfoot' => true, 'tr' => true
+               ]
+       ];
+
+       public static $impliedEndTagsSet = [
+               self::HTML_NAMESPACE => [
+                       'dd' => true, 'dt' => true, 'li' => true, 'optgroup' => true,
+                       'option' => true, 'p' => true, 'rb' => true, 'rp' => true,
+                       'rt' => true, 'rtc' => true
+               ]
+       ];
+
+       public static $thoroughImpliedEndTagsSet = [
+               self::HTML_NAMESPACE => [
+                       'caption' => true, 'colgroup' => true, 'dd' => true, 'dt' => true,
+                       'li' => true, 'optgroup' => true, 'option' => true, 'p' => true,
+                       'rb' => true, 'rp' => true, 'rt' => true, 'rtc' => true,
+                       'tbody' => true, 'td' => true, 'tfoot' => true, 'th' => true,
+                       'thead' => true, 'tr' => true
+               ]
+       ];
+
+       public static $tableCellSet = [
+               self::HTML_NAMESPACE => [
+                       'td' => true, 'th' => true
+               ]
+       ];
+       public static $tableContextSet = [
+               self::HTML_NAMESPACE => [
+                       'table' => true, 'template' => true, 'html' => true
+               ]
+       ];
+
+       public static $tableBodyContextSet = [
+               self::HTML_NAMESPACE => [
+                       'tbody' => true, 'tfoot' => true, 'thead' => true,
+                       'template' => true, 'html' => true
+               ]
+       ];
+
+       public static $tableRowContextSet = [
+               self::HTML_NAMESPACE => [
+                       'tr' => true, 'template' => true, 'html' => true
+               ]
+       ];
+
+       // See https://html.spec.whatwg.org/multipage/forms.html#form-associated-element
+       public static $formAssociatedSet = [
+               self::HTML_NAMESPACE => [
+                       'button' => true, 'fieldset' => true, 'input' => true,
+                       'keygen' => true, 'object' => true, 'output' => true,
+                       'select' => true, 'textarea' => true, 'img' => true
+               ]
+       ];
+
+       public static $inScopeSet = [
+               self::HTML_NAMESPACE => [
+                       'applet' => true, 'caption' => true, 'html' => true,
+                       'marquee' => true, 'object' => true,
+                       'table' => true, 'td' => true, 'template' => true,
+                       'th' => true
+               ],
+               self::SVG_NAMESPACE => [
+                       'foreignobject' => true, 'desc' => true, 'title' => true
+               ],
+               self::MATHML_NAMESPACE => [
+                       'mi' => true, 'mo' => true, 'mn' => true, 'ms' => true,
+                       'mtext' => true, 'annotation-xml' => true
+               ]
+       ];
+
+       private static $inListItemScopeSet = null;
+       public static function inListItemScopeSet() {
+               if ( self::$inListItemScopeSet === null ) {
+                       self::$inListItemScopeSet = self::$inScopeSet;
+                       self::$inListItemScopeSet[self::HTML_NAMESPACE]['ol'] = true;
+                       self::$inListItemScopeSet[self::HTML_NAMESPACE]['ul'] = true;
+               }
+               return self::$inListItemScopeSet;
+       }
+
+       private static $inButtonScopeSet = null;
+       public static function inButtonScopeSet() {
+               if ( self::$inButtonScopeSet === null ) {
+                       self::$inButtonScopeSet = self::$inScopeSet;
+                       self::$inButtonScopeSet[self::HTML_NAMESPACE]['button'] = true;
+               }
+               return self::$inButtonScopeSet;
+       }
+
+       public static $inTableScopeSet = [
+               self::HTML_NAMESPACE => [
+                       'html' => true, 'table' => true, 'template' => true
+               ]
+       ];
+
+       public static $inInvertedSelectScopeSet = [
+               self::HTML_NAMESPACE => [
+                       'option' => true, 'optgroup' => true
+               ]
+       ];
+
+       public static $mathmlTextIntegrationPointSet = [
+               self::MATHML_NAMESPACE => [
+                       'mi' => true, 'mo' => true, 'mn' => true, 'ms' => true,
+                       'mtext' => true
+               ]
+       ];
+
+       public static $htmlIntegrationPointSet = [
+               self::SVG_NAMESPACE => [
+                       'foreignobject' => true,
+                       'desc' => true,
+                       'title' => true
+               ]
+       ];
+
+       // For tidy compatibility.
+       public static $tidyPWrapSet = [
+               self::HTML_NAMESPACE => [
+                       'body' => true, 'blockquote' => true,
+                       // We parse with <body> as the fragment context, but the top-level
+                       // element on the stack is actually <html>.  We could use the
+                       // "adjusted current node" everywhere to work around this, but it's
+                       // easier just to add <html> to the p-wrap set.
+                       'html' => true,
+               ],
+       ];
+       public static $tidyInlineSet = [
+               self::HTML_NAMESPACE => [
+                       'a' => true, 'abbr' => true, 'acronym' => true, 'applet' => true,
+                       'b' => true, 'basefont' => true, 'bdo' => true, 'big' => true,
+                       'br' => true, 'button' => true, 'cite' => true, 'code' => true,
+                       'dfn' => true, 'em' => true, 'font' => true, 'i' => true,
+                       'iframe' => true, 'img' => true, 'input' => true, 'kbd' => true,
+                       'label' => true, 'legend' => true, 'map' => true, 'object' => true,
+                       'param' => true, 'q' => true, 'rb' => true, 'rbc' => true,
+                       'rp' => true, 'rt' => true, 'rtc' => true, 'ruby' => true,
+                       's' => true, 'samp' => true, 'select' => true, 'small' => true,
+                       'span' => true, 'strike' => true, 'strong' => true, 'sub' => true,
+                       'sup' => true, 'textarea' => true, 'tt' => true, 'u' => true,
+                       'var' => true,
+               ],
+       ];
+}
+
+/**
+ * A BalanceElement is a simplified version of a DOM Node.  The main
+ * difference is that we only keep BalanceElements around for nodes
+ * currently on the BalanceStack of open elements.  As soon as an
+ * element is closed, with some minor exceptions relating to the
+ * tree builder "adoption agency algorithm", the element and all its
+ * children are serialized to a string using the flatten() method.
+ * This keeps our memory usage low.
+ *
+ * @ingroup Parser
+ * @since 1.27
+ */
+class BalanceElement {
+       /**
+        * The namespace of the element.
+        * @var string $namespaceURI
+        */
+       public $namespaceURI;
+       /**
+        * The lower-cased name of the element.
+        * @var string $localName
+        */
+       public $localName;
+       /**
+        * Attributes for the element, in array form
+        * @var array $attribs
+        */
+       public $attribs;
+
+       /**
+        * Parent of this element, or the string "flat" if this element has
+        * already been flattened into its parent.
+        * @var string|null $parent
+        */
+       public $parent;
+
+       /**
+        * An array of children of this element.  Typically only the last
+        * child will be an actual BalanceElement object; the rest will
+        * be strings, representing either text nodes or flattened
+        * BalanceElement objects.
+        * @var array $children
+        */
+       public $children;
+
+       /**
+        * A unique string identifier for Noah's Ark purposes, lazy initialized
+        */
+       private $noahKey;
+
+       /**
+        * The next active formatting element in the list, or null if this is the
+        * end of the AFE list or if the element is not in the AFE list.
+        */
+       public $nextAFE;
+
+       /**
+        * The previous active formatting element in the list, or null if this is
+        * the start of the list or if the element is not in the AFE list.
+        */
+       public $prevAFE;
+
+       /**
+        * The next element in the Noah's Ark species bucket.
+        */
+       public $nextNoah;
+
+       /**
+        * Make a new BalanceElement corresponding to the HTML DOM Element
+        * with the given localname, namespace, and attributes.
+        *
+        * @param string $namespaceURI The namespace of the element.
+        * @param string $localName The lowercased name of the tag.
+        * @param array $attribs Attributes of the element
+        */
+       public function __construct( $namespaceURI, $localName, array $attribs ) {
+               $this->localName = $localName;
+               $this->namespaceURI = $namespaceURI;
+               $this->attribs = $attribs;
+               $this->contents = '';
+               $this->parent = null;
+               $this->children = [];
+       }
+
+       /**
+        * Remove the given child from this element.
+        * @param BalanceElement $elt
+        */
+       private function removeChild( BalanceElement $elt ) {
+               Assert::precondition(
+                       $this->parent !== 'flat', "Can't removeChild after flattening $this"
+               );
+               Assert::parameter(
+                       $elt->parent === $this, 'elt', 'must have $this as a parent'
+               );
+               $idx = array_search( $elt, $this->children, true );
+               Assert::parameter( $idx !== false, '$elt', 'must be a child of $this' );
+               $elt->parent = null;
+               array_splice( $this->children, $idx, 1 );
+       }
+
+       /**
+        * Find $a in the list of children and insert $b before it.
+        * @param BalanceElement $a
+        * @param BalanceElement|string $b
+        */
+       public function insertBefore( BalanceElement $a, $b ) {
+               Assert::precondition(
+                       $this->parent !== 'flat', "Can't insertBefore after flattening."
+               );
+               $idx = array_search( $a, $this->children, true );
+               Assert::parameter( $idx !== false, '$a', 'must be a child of $this' );
+               if ( is_string( $b ) ) {
+                       array_splice( $this->children, $idx, 0, [ $b ] );
+               } else {
+                       Assert::parameter( $b->parent !== 'flat', '$b', "Can't be flat" );
+                       if ( $b->parent !== null ) {
+                               $b->parent->removeChild( $b );
+                       }
+                       array_splice( $this->children, $idx, 0, [ $b ] );
+                       $b->parent = $this;
+               }
+       }
+
+       /**
+        * Append $elt to the end of the list of children.
+        * @param BalanceElement|string $elt
+        */
+       public function appendChild( $elt ) {
+               Assert::precondition(
+                       $this->parent !== 'flat', "Can't appendChild after flattening."
+               );
+               if ( is_string( $elt ) ) {
+                       array_push( $this->children, $elt );
+                       return;
+               }
+               // Remove $elt from parent, if it had one.
+               if ( $elt->parent !== null ) {
+                       $elt->parent->removeChild( $elt );
+               }
+               array_push( $this->children, $elt );
+               $elt->parent = $this;
+       }
+
+       /**
+        * Transfer all of the children of $elt to $this.
+        * @param BalanceElement $elt
+        */
+       public function adoptChildren( BalanceElement $elt ) {
+               Assert::precondition(
+                       $elt->parent !== 'flat', "Can't adoptChildren after flattening."
+               );
+               foreach ( $elt->children as $child ) {
+                       if ( !is_string( $child ) ) {
+                               // This is an optimization which avoids an O(n^2) set of
+                               // array_splice operations.
+                               $child->parent = null;
+                       }
+                       $this->appendChild( $child );
+               }
+               $elt->children = [];
+       }
+
+       /**
+        * Flatten this node and all of its children into a string, as specified
+        * by the HTML serialization specification, and replace this node
+        * in its parent by that string.
+        *
+        * @see __toString()
+        */
+       public function flatten( $tidyCompat = false ) {
+               Assert::parameter( $this->parent !== null, '$this', 'must be a child' );
+               Assert::parameter( $this->parent !== 'flat', '$this', 'already flat' );
+               $idx = array_search( $this, $this->parent->children, true );
+               Assert::parameter(
+                       $idx !== false, '$this', 'must be a child of its parent'
+               );
+               if ( $tidyCompat ) {
+                       $blank = true;
+                       foreach ( $this->children as $elt ) {
+                               if ( !is_string( $elt ) ) {
+                                       $elt = $elt->flatten( $tidyCompat );
+                               }
+                               if ( $blank && preg_match( '/[^\t\n\f\r ]/', $elt ) ) {
+                                       $blank = false;
+                               }
+                       }
+                       if ( $this->isHtmlNamed( 'mw:p-wrap' ) ) {
+                               $this->localName = 'p';
+                       } elseif ( $blank ) {
+                               // Add 'mw-empty-elt' class so elements can be hidden via CSS
+                               // for compatibility with legacy tidy.
+                               if ( !count( $this->attribs ) &&
+                                       ( $this->localName === 'tr' || $this->localName === 'li' )
+                               ) {
+                                       $this->attribs = [ 'class' => "mw-empty-elt" ];
+                               }
+                               $blank = false;
+                       }
+                       $flat = $blank ? '' : "{$this}";
+               } else {
+                       $flat = "{$this}";
+               }
+               $this->parent->children[$idx] = $flat;
+               $this->parent = 'flat'; # for assertion checking
+               return $flat;
+       }
+
+       /**
+        * Serialize this node and all of its children to a string, as specified
+        * by the HTML serialization specification.
+        *
+        * @return string The serialization of the BalanceElement
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#serialising-html-fragments
+        */
+       public function __toString() {
+               $encAttribs = '';
+               foreach ( $this->attribs as $name => $value ) {
+                       $encValue = Sanitizer::encodeAttribute( $value );
+                       $encAttribs .= " $name=\"$encValue\"";
+               }
+               if ( !$this->isA( BalanceSets::$emptyElementSet ) ) {
+                       $out = "<{$this->localName}{$encAttribs}>";
+                       $len = strlen( $out );
+                       // flatten children
+                       foreach ( $this->children as $elt ) {
+                               $out .= "{$elt}";
+                       }
+                       $out .= "</{$this->localName}>";
+                       if (
+                               $this->isA( BalanceSets::$extraLinefeedSet ) &&
+                               $out[$len] === "\n"
+                       ) {
+                               // Double the linefeed after pre/listing/textarea
+                               // according to the HTML5 fragment serialization algorithm.
+                               $out = substr( $out, 0, $len + 1 ) .
+                                       substr( $out, $len );
+                       }
+               } else {
+                       $out = "<{$this->localName}{$encAttribs} />";
+                       Assert::invariant(
+                               count( $this->children ) === 0,
+                               "Empty elements shouldn't have children."
+                       );
+               }
+               return $out;
+       }
+
+       # Utility functions on BalanceElements.
+
+       /**
+        * Determine if $this represents a specific HTML tag, is a member of
+        * a tag set, or is equal to another BalanceElement.
+        *
+        * @param BalanceElement|array|string $set The target BalanceElement,
+        *   set (from the BalanceSets class), or string (HTML tag name).
+        * @return bool
+        */
+       public function isA( $set ) {
+               if ( $set instanceof BalanceElement ) {
+                       return $this === $set;
+               } elseif ( is_array( $set ) ) {
+                       return isset( $set[$this->namespaceURI] ) &&
+                               isset( $set[$this->namespaceURI][$this->localName] );
+               } else {
+                       # assume this is an HTML element name.
+                       return $this->isHtml() && $this->localName === $set;
+               }
+       }
+
+       /**
+        * Determine if this element is an HTML element with the specified name
+        * @param string $tagName
+        * @return bool
+        */
+       public function isHtmlNamed( $tagName ) {
+               return $this->namespaceURI === BalanceSets::HTML_NAMESPACE
+                       && $this->localName === $tagName;
+       }
+
+       /**
+        * Determine if $this represents an element in the HTML namespace.
+        *
+        * @return bool
+        */
+       public function isHtml() {
+               return $this->namespaceURI === BalanceSets::HTML_NAMESPACE;
+       }
+
+       /**
+        * Determine if $this represents a MathML text integration point,
+        * as defined in the HTML5 specification.
+        *
+        * @return bool
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#mathml-text-integration-point
+        */
+       public function isMathmlTextIntegrationPoint() {
+               return $this->isA( BalanceSets::$mathmlTextIntegrationPointSet );
+       }
+
+       /**
+        * Determine if $this represents an HTML integration point,
+        * as defined in the HTML5 specification.
+        *
+        * @return bool
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
+        */
+       public function isHtmlIntegrationPoint() {
+               if ( $this->isA( BalanceSets::$htmlIntegrationPointSet ) ) {
+                       return true;
+               }
+               if (
+                       $this->namespaceURI === BalanceSets::MATHML_NAMESPACE &&
+                       $this->localName === 'annotation-xml' &&
+                       isset( $this->attribs['encoding'] ) &&
+                       ( strcasecmp( $this->attribs['encoding'], 'text/html' ) == 0 ||
+                       strcasecmp( $this->attribs['encoding'], 'application/xhtml+xml' ) == 0 )
+               ) {
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Get a string key for the Noah's Ark algorithm
+        */
+       public function getNoahKey() {
+               if ( $this->noahKey === null ) {
+                       $attribs = $this->attribs;
+                       ksort( $attribs );
+                       $this->noahKey = serialize( [ $this->namespaceURI, $this->localName, $attribs ] );
+               }
+               return $this->noahKey;
+       }
+}
+
+/**
+ * The "stack of open elements" as defined in the HTML5 tree builder
+ * spec.  This contains methods to ensure that content (start tags, text)
+ * are inserted at the correct place in the output string, and to
+ * flatten BalanceElements are they are closed to avoid holding onto
+ * a complete DOM tree for the document in memory.
+ *
+ * The stack defines a PHP iterator to traverse it in "reverse order",
+ * that is, the most-recently-added element is visited first in a
+ * foreach loop.
+ *
+ * @ingroup Parser
+ * @since 1.27
+ * @see https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements
+ */
+class BalanceStack implements IteratorAggregate {
+       /**
+        * Backing storage for the stack.
+        * @var array $elements
+        */
+       private $elements = [];
+       /**
+        * Foster parent mode determines how nodes are inserted into the
+        * stack.
+        * @var bool $fosterParentMode
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#foster-parent
+        */
+       public $fosterParentMode = false;
+       /**
+        * Tidy compatibility mode, determines behavior of body/blockquote
+        */
+       public $tidyCompat = false;
+       /**
+        * Reference to the current element
+        */
+       public $currentNode;
+
+       /**
+        * Create a new BalanceStack with a single BalanceElement on it,
+        * representing the root &lt;html&gt; node.
+        */
+       public function __construct() {
+               # always a root <html> element on the stack
+               array_push(
+                       $this->elements,
+                       new BalanceElement( BalanceSets::HTML_NAMESPACE, 'html', [] )
+               );
+               $this->currentNode = $this->elements[0];
+       }
+
+       /**
+        * Return a string representing the output of the tree builder:
+        * all the children of the root &lt;html&gt; node.
+        * @return string
+        */
+       public function getOutput() {
+               // Don't include the outer '<html>....</html>'
+               $out = '';
+               foreach ( $this->elements[0]->children as $elt ) {
+                       $out .= is_string( $elt ) ? $elt :
+                               $elt->flatten( $this->tidyCompat );
+               }
+               return $out;
+       }
+
+       /**
+        * Insert a comment at the appropriate place for inserting a node.
+        * @param string $value Content of the comment.
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#insert-a-comment
+        */
+       public function insertComment( $value ) {
+               // Just another type of text node, except for tidy p-wrapping.
+               return $this->insertText( '<!--' . $value . '-->', true );
+       }
+
+       /**
+        * Insert text at the appropriate place for inserting a node.
+        * @param string $value
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#appropriate-place-for-inserting-a-node
+        */
+       public function insertText( $value, $isComment = false ) {
+               if (
+                       $this->fosterParentMode &&
+                       $this->currentNode->isA( BalanceSets::$tableSectionRowSet )
+               ) {
+                       $this->fosterParent( $value );
+               } elseif (
+                       $this->tidyCompat && !$isComment &&
+                       $this->currentNode->isA( BalanceSets::$tidyPWrapSet )
+               ) {
+                       $this->insertHTMLELement( 'mw:p-wrap', [] );
+                       return $this->insertText( $value );
+               } else {
+                       $this->currentNode->appendChild( $value );
+               }
+       }
+
+       /**
+        * Insert a BalanceElement at the appropriate place, pushing it
+        * on to the open elements stack.
+        * @param string $namespaceURI The element namespace
+        * @param string $tag The tag name
+        * @param string $attribs Normalized attributes, as a string.
+        * @return BalanceElement
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#insert-a-foreign-element
+        */
+       public function insertForeignElement( $namespaceURI, $tag, $attribs ) {
+               return $this->insertElement(
+                       new BalanceElement( $namespaceURI, $tag, $attribs )
+               );
+       }
+
+       /**
+        * Insert an HTML element at the appropriate place, pushing it on to
+        * the open elements stack.
+        * @param string $tag The tag name
+        * @param string $attribs Normalized attributes, as a string.
+        * @return BalanceElement
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#insert-an-html-element
+        */
+       public function insertHTMLElement( $tag, $attribs ) {
+               return $this->insertForeignElement(
+                       BalanceSets::HTML_NAMESPACE, $tag, $attribs
+               );
+       }
+
+       /**
+        * Insert an element at the appropriate place and push it on to the
+        * open elements stack.
+        * @param BalanceElement $elt
+        * @return BalanceElement
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#appropriate-place-for-inserting-a-node
+        */
+       public function insertElement( BalanceElement $elt ) {
+               if (
+                       $this->currentNode->isHtmlNamed( 'mw:p-wrap' ) &&
+                       !$elt->isA( BalanceSets::$tidyInlineSet )
+               ) {
+                       // Tidy compatibility.
+                       $this->pop();
+               }
+               if (
+                       $this->fosterParentMode &&
+                       $this->currentNode->isA( BalanceSets::$tableSectionRowSet )
+               ) {
+                       $elt = $this->fosterParent( $elt );
+               } else {
+                       $this->currentNode->appendChild( $elt );
+               }
+               Assert::invariant( $elt->parent !== null, "$elt must be in tree" );
+               Assert::invariant( $elt->parent !== 'flat', "$elt must not have been previous flattened" );
+               array_push( $this->elements, $elt );
+               $this->currentNode = $elt;
+               return $elt;
+       }
+
+       /**
+        * Determine if the stack has $tag in scope.
+        * @param BalanceElement|array|string $tag
+        * @return bool
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
+        */
+       public function inScope( $tag ) {
+               return $this->inSpecificScope( $tag, BalanceSets::$inScopeSet );
+       }
+
+       /**
+        * Determine if the stack has $tag in button scope.
+        * @param BalanceElement|array|string $tag
+        * @return bool
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
+        */
+       public function inButtonScope( $tag ) {
+               return $this->inSpecificScope( $tag, BalanceSets::inButtonScopeSet() );
+       }
+
+       /**
+        * Determine if the stack has $tag in list item scope.
+        * @param BalanceElement|array|string $tag
+        * @return bool
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-list-item-scope
+        */
+       public function inListItemScope( $tag ) {
+               return $this->inSpecificScope( $tag, BalanceSets::inListItemScopeSet() );
+       }
+
+       /**
+        * Determine if the stack has $tag in table scope.
+        * @param BalanceElement|array|string $tag
+        * @return bool
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-table-scope
+        */
+       public function inTableScope( $tag ) {
+               return $this->inSpecificScope( $tag, BalanceSets::$inTableScopeSet );
+       }
+
+       /**
+        * Determine if the stack has $tag in select scope.
+        * @param BalanceElement|array|string $tag
+        * @return bool
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-select-scope
+        */
+       public function inSelectScope( $tag ) {
+               // Can't use inSpecificScope to implement this, since it involves
+               // *inverting* a set of tags.  Implement manually.
+               foreach ( $this as $elt ) {
+                       if ( $elt->isA( $tag ) ) {
+                               return true;
+                       }
+                       if ( !$elt->isA( BalanceSets::$inInvertedSelectScopeSet ) ) {
+                               return false;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Determine if the stack has $tag in a specific scope, $set.
+        * @param BalanceElement|array|string $tag
+        * @param BalanceElement|array|string $set
+        * @return bool
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-the-specific-scope
+        */
+       public function inSpecificScope( $tag, $set ) {
+               foreach ( $this as $elt ) {
+                       if ( $elt->isA( $tag ) ) {
+                               return true;
+                       }
+                       if ( $elt->isA( $set ) ) {
+                               return false;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Generate implied end tags.
+        * @param string $butnot
+        * @param bool $thorough True if we should generate end tags thoroughly.
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
+        */
+       public function generateImpliedEndTags( $butnot = null, $thorough = false ) {
+               $endTagSet = $thorough ?
+                       BalanceSets::$thoroughImpliedEndTagsSet :
+                       BalanceSets::$impliedEndTagsSet;
+               while ( $this->currentNode ) {
+                       if ( $butnot !== null && $this->currentNode->isHtmlNamed( $butnot ) ) {
+                               break;
+                       }
+                       if ( !$this->currentNode->isA( $endTagSet ) ) {
+                               break;
+                       }
+                       $this->pop();
+               }
+       }
+
+       /**
+        * Return the adjusted current node.
+        */
+       public function adjustedCurrentNode( $fragmentContext ) {
+               return ( $fragmentContext && count( $this->elements ) === 1 ) ?
+                       $fragmentContext : $this->currentNode;
+       }
+
+       /**
+        * Return an iterator over this stack which visits the current node
+        * first, and the root node last.
+        * @return Iterator
+        */
+       public function getIterator() {
+               return new ReverseArrayIterator( $this->elements );
+       }
+
+       /**
+        * Return the BalanceElement at the given position $idx, where
+        * position 0 represents the root element.
+        * @param int $idx
+        * @return BalanceElement
+        */
+       public function node( $idx ) {
+               return $this->elements[ $idx ];
+       }
+
+       /**
+        * Replace the element at position $idx in the BalanceStack with $elt.
+        * @param int $idx
+        * @param BalanceElement $elt
+        */
+       public function replaceAt( $idx, BalanceElement $elt ) {
+               Assert::precondition(
+                       $this->elements[$idx]->parent !== 'flat',
+                       'Replaced element should not have already been flattened.'
+               );
+               Assert::precondition(
+                       $elt->parent !== 'flat',
+                       'New element should not have already been flattened.'
+               );
+               $this->elements[$idx] = $elt;
+               if ( $idx === count( $this->elements ) - 1 ) {
+                       $this->currentNode = $elt;
+               }
+       }
+
+       /**
+        * Return the position of the given BalanceElement, set, or
+        * HTML tag name string in the BalanceStack.
+        * @param BalanceElement|array|string $tag
+        * @return int
+        */
+       public function indexOf( $tag ) {
+               for ( $i = count( $this->elements ) - 1; $i >= 0; $i-- ) {
+                       if ( $this->elements[$i]->isA( $tag ) ) {
+                               return $i;
+                       }
+               }
+               return -1;
+       }
+
+       /**
+        * Return the number of elements currently in the BalanceStack.
+        * @return int
+        */
+       public function length() {
+               return count( $this->elements );
+       }
+
+       /**
+        * Remove the current node from the BalanceStack, flattening it
+        * in the process.
+        */
+       public function pop() {
+               $elt = array_pop( $this->elements );
+               if ( count( $this->elements ) ) {
+                       $this->currentNode = $this->elements[ count( $this->elements ) - 1 ];
+               } else {
+                       $this->currentNode = null;
+               }
+               if ( !$elt->isHtmlNamed( 'mw:p-wrap' ) ) {
+                       $elt->flatten( $this->tidyCompat );
+               }
+       }
+
+       /**
+        * Remove all nodes up to and including position $idx from the
+        * BalanceStack, flattening them in the process.
+        * @param int $idx
+        */
+       public function popTo( $idx ) {
+               $length = count( $this->elements );
+               for ( $length = count( $this->elements ); $length > $idx; $length-- ) {
+                       $this->pop();
+               }
+       }
+
+       /**
+        * Pop elements off the stack up to and including the first
+        * element with the specified HTML tagname (or matching the given
+        * set).
+        * @param BalanceElement|array|string $tag
+        */
+       public function popTag( $tag ) {
+               while ( $this->currentNode ) {
+                       if ( $this->currentNode->isA( $tag ) ) {
+                               $this->pop();
+                               break;
+                       }
+                       $this->pop();
+               }
+       }
+
+       /**
+        * Pop elements off the stack *not including* the first element
+        * in the specified set.
+        * @param BalanceElement|array|string $set
+        */
+       public function clearToContext( $set ) {
+               // Note that we don't loop to 0. Never pop the <html> elt off.
+               for ( $length = count( $this->elements ); $length > 1; $length-- ) {
+                       if ( $this->currentNode->isA( $set ) ) {
+                               break;
+                       }
+                       $this->pop();
+               }
+       }
+
+       /**
+        * Remove the given $elt from the BalanceStack, optionally
+        * flattening it in the process.
+        * @param BalanceElement $elt The element to remove.
+        * @param bool $flatten Whether to flatten the removed element.
+        */
+       public function removeElement( BalanceElement $elt, $flatten = true ) {
+               Assert::parameter(
+                       $elt->parent !== 'flat',
+                       '$elt',
+                       '$elt should not already have been flattened.'
+               );
+               Assert::parameter(
+                       $elt->parent->parent !== 'flat',
+                       '$elt',
+                       'The parent of $elt should not already have been flattened.'
+               );
+               $idx = array_search( $elt, $this->elements, true );
+               Assert::parameter( $idx !== false, '$elt', 'must be in stack' );
+               array_splice( $this->elements, $idx, 1 );
+               if ( $idx === count( $this->elements ) ) {
+                       $this->currentNode = $this->elements[$idx - 1];
+               }
+               if ( $flatten ) {
+                       // serialize $elt into its parent
+                       // otherwise, it will eventually serialize when the parent
+                       // is serialized, we just hold onto the memory for its
+                       // tree of objects a little longer.
+                       $elt->flatten( $this->tidyCompat );
+               }
+               Assert::postcondition(
+                       array_search( $elt, $this->elements, true ) === false,
+                       '$elt should no longer be in open elements stack'
+               );
+       }
+
+       /**
+        * Find $a in the BalanceStack and insert $b after it.
+        * @param BalanceElement $a
+        * @param BalanceElement $b
+        */
+       public function insertAfter( BalanceElement $a, BalanceElement $b ) {
+               $idx = $this->indexOf( $a );
+               Assert::parameter( $idx !== false, '$a', 'must be in stack' );
+               if ( $idx === count( $this->elements ) - 1 ) {
+                       array_push( $this->elements, $b );
+                       $this->currentNode = $b;
+               } else {
+                       array_splice( $this->elements, $idx + 1, 0, [ $b ] );
+               }
+       }
+
+       # Fostering and adoption.
+
+       /**
+        * Foster parent the given $elt in the stack of open elements.
+        * @param BalanceElement|string $elt
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#foster-parent
+        */
+       private function fosterParent( $elt ) {
+               $lastTable = $this->indexOf( 'table' );
+               $lastTemplate = $this->indexOf( 'template' );
+               $parent = null;
+               $before = null;
+
+               if ( $lastTemplate >= 0 && ( $lastTable < 0 || $lastTemplate > $lastTable ) ) {
+                       $parent = $this->elements[$lastTemplate];
+               } elseif ( $lastTable >= 0 ) {
+                       $parent = $this->elements[$lastTable]->parent;
+                       # Assume all tables have parents, since we're not running scripts!
+                       Assert::invariant(
+                               $parent !== null, "All tables should have parents"
+                       );
+                       $before = $this->elements[$lastTable];
+               } else {
+                       $parent = $this->elements[0]; // the `html` element.
+               }
+
+               if ( $this->tidyCompat ) {
+                       if ( is_string( $elt ) ) {
+                               // We're fostering text: do we need a p-wrapper?
+                               if ( $parent->isA( BalanceSets::$tidyPWrapSet ) ) {
+                                       $this->insertHTMLElement( 'mw:p-wrap', [] );
+                                       $this->insertText( $elt );
+                                       return $elt;
+                               }
+                       } else {
+                               // We're fostering an element; do we need to merge p-wrappers?
+                               if ( $elt->isHtmlNamed( 'mw:p-wrap' ) ) {
+                                       $idx = $before ?
+                                               array_search( $before, $parent->children, true ) :
+                                               count( $parent->children );
+                                       $after = $idx > 0 ? $parent->children[$idx - 1] : '';
+                                       if (
+                                               $after instanceof BalanceElement &&
+                                               $after->isHtmlNamed( 'mw:p-wrap' )
+                                       ) {
+                                               return $after; // Re-use existing p-wrapper.
+                                       }
+                               }
+                       }
+               }
+
+               if ( $before ) {
+                       $parent->insertBefore( $before, $elt );
+               } else {
+                       $parent->appendChild( $elt );
+               }
+               return $elt;
+       }
+
+       /**
+        * Run the "adoption agency algoritm" (AAA) for the given subject
+        * tag name.
+        * @param string $tag The subject tag name.
+        * @param BalanceActiveFormattingElements $afe The current
+        *   active formatting elements list.
+        * @return true if the adoption agency algorithm "did something", false
+        *   if more processing is required by the caller.
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#adoption-agency-algorithm
+        */
+       public function adoptionAgency( $tag, $afe ) {
+               // If the current node is an HTML element whose tag name is subject,
+               // and the current node is not in the list of active formatting
+               // elements, then pop the current node off the stack of open
+               // elements and abort these steps.
+               if (
+                       $this->currentNode->isHtmlNamed( $tag ) &&
+                       !$afe->isInList( $this->currentNode )
+               ) {
+                       $this->pop();
+                       return true; // no more handling required
+               }
+
+               // Let outer loop counter be zero.
+               $outer = 0;
+
+               // Outer loop: If outer loop counter is greater than or
+               // equal to eight, then abort these steps.
+               while ( $outer < 8 ) {
+                       // Increment outer loop counter by one.
+                       $outer++;
+
+                       // Let the formatting element be the last element in the list
+                       // of active formatting elements that: is between the end of
+                       // the list and the last scope marker in the list, if any, or
+                       // the start of the list otherwise, and has the same tag name
+                       // as the token.
+                       $fmtelt = $afe->findElementByTag( $tag );
+
+                       // If there is no such node, then abort these steps and instead
+                       // act as described in the "any other end tag" entry below.
+                       if ( !$fmtelt ) {
+                               return false; // false means handle by the default case
+                       }
+
+                       // Otherwise, if there is such a node, but that node is not in
+                       // the stack of open elements, then this is a parse error;
+                       // remove the element from the list, and abort these steps.
+                       $index = $this->indexOf( $fmtelt );
+                       if ( $index < 0 ) {
+                               $afe->remove( $fmtelt );
+                               return true;   // true means no more handling required
+                       }
+
+                       // Otherwise, if there is such a node, and that node is also in
+                       // the stack of open elements, but the element is not in scope,
+                       // then this is a parse error; ignore the token, and abort
+                       // these steps.
+                       if ( !$this->inScope( $fmtelt ) ) {
+                               return true;
+                       }
+
+                       // Let the furthest block be the topmost node in the stack of
+                       // open elements that is lower in the stack than the formatting
+                       // element, and is an element in the special category. There
+                       // might not be one.
+                       $furthestblock = null;
+                       $furthestblockindex = -1;
+                       $stacklen = $this->length();
+                       for ( $i = $index+1; $i < $stacklen; $i++ ) {
+                               if ( $this->node( $i )->isA( BalanceSets::$specialSet ) ) {
+                                       $furthestblock = $this->node( $i );
+                                       $furthestblockindex = $i;
+                                       break;
+                               }
+                       }
+
+                       // If there is no furthest block, then the UA must skip the
+                       // subsequent steps and instead just pop all the nodes from the
+                       // bottom of the stack of open elements, from the current node
+                       // up to and including the formatting element, and remove the
+                       // formatting element from the list of active formatting
+                       // elements.
+                       if ( !$furthestblock ) {
+                               $this->popTag( $fmtelt );
+                               $afe->remove( $fmtelt );
+                               return true;
+                       } else {
+                               // Let the common ancestor be the element immediately above
+                               // the formatting element in the stack of open elements.
+                               $ancestor = $this->node( $index-1 );
+
+                               // Let a bookmark note the position of the formatting
+                               // element in the list of active formatting elements
+                               // relative to the elements on either side of it in the
+                               // list.
+                               $BOOKMARK = new BalanceElement( '[bookmark]', '[bookmark]', [] );
+                               $afe->insertAfter( $fmtelt, $BOOKMARK );
+
+                               // Let node and last node be the furthest block.
+                               $node = $furthestblock;
+                               $lastnode = $furthestblock;
+                               $nodeindex = $furthestblockindex;
+                               $isAFE = false;
+
+                               // Let inner loop counter be zero.
+                               $inner = 0;
+
+                               while ( true ) {
+
+                                       // Increment inner loop counter by one.
+                                       $inner++;
+
+                                       // Let node be the element immediately above node in
+                                       // the stack of open elements, or if node is no longer
+                                       // in the stack of open elements (e.g. because it got
+                                       // removed by this algorithm), the element that was
+                                       // immediately above node in the stack of open elements
+                                       // before node was removed.
+                                       $node = $this->node( --$nodeindex );
+
+                                       // If node is the formatting element, then go
+                                       // to the next step in the overall algorithm.
+                                       if ( $node === $fmtelt ) break;
+
+                                       // If the inner loop counter is greater than three and node
+                                       // is in the list of active formatting elements, then remove
+                                       // node from the list of active formatting elements.
+                                       $isAFE = $afe->isInList( $node );
+                                       if ( $inner > 3 && $isAFE ) {
+                                               $afe->remove( $node );
+                                               $isAFE = false;
+                                       }
+
+                                       // If node is not in the list of active formatting
+                                       // elements, then remove node from the stack of open
+                                       // elements and then go back to the step labeled inner
+                                       // loop.
+                                       if ( !$isAFE ) {
+                                               // Don't flatten here, since we're about to relocate
+                                               // parts of this $node.
+                                               $this->removeElement( $node, false );
+                                               continue;
+                                       }
+
+                                       // Create an element for the token for which the
+                                       // element node was created with common ancestor as
+                                       // the intended parent, replace the entry for node
+                                       // in the list of active formatting elements with an
+                                       // entry for the new element, replace the entry for
+                                       // node in the stack of open elements with an entry for
+                                       // the new element, and let node be the new element.
+                                       $newelt = new BalanceElement(
+                                               $node->namespaceURI, $node->localName, $node->attribs );
+                                       $afe->replace( $node, $newelt );
+                                       $this->replaceAt( $nodeindex, $newelt );
+                                       $node = $newelt;
+
+                                       // If last node is the furthest block, then move the
+                                       // aforementioned bookmark to be immediately after the
+                                       // new node in the list of active formatting elements.
+                                       if ( $lastnode === $furthestblock ) {
+                                               $afe->remove( $BOOKMARK );
+                                               $afe->insertAfter( $newelt, $BOOKMARK );
+                                       }
+
+                                       // Insert last node into node, first removing it from
+                                       // its previous parent node if any.
+                                       $node->appendChild( $lastnode );
+
+                                       // Let last node be node.
+                                       $lastnode = $node;
+                               }
+
+                               // If the common ancestor node is a table, tbody, tfoot,
+                               // thead, or tr element, then, foster parent whatever last
+                               // node ended up being in the previous step, first removing
+                               // it from its previous parent node if any.
+                               if (
+                                       $this->fosterParentMode &&
+                                       $ancestor->isA( BalanceSets::$tableSectionRowSet )
+                               ) {
+                                       $this->fosterParent( $lastnode );
+                               } else {
+                                       // Otherwise, append whatever last node ended up being in
+                                       // the previous step to the common ancestor node, first
+                                       // removing it from its previous parent node if any.
+                                       $ancestor->appendChild( $lastnode );
+                               }
+
+                               // Create an element for the token for which the
+                               // formatting element was created, with furthest block
+                               // as the intended parent.
+                               $newelt2 = new BalanceElement(
+                                       $fmtelt->namespaceURI, $fmtelt->localName, $fmtelt->attribs );
+
+                               // Take all of the child nodes of the furthest block and
+                               // append them to the element created in the last step.
+                               $newelt2->adoptChildren( $furthestblock );
+
+                               // Append that new element to the furthest block.
+                               $furthestblock->appendChild( $newelt2 );
+
+                               // Remove the formatting element from the list of active
+                               // formatting elements, and insert the new element into the
+                               // list of active formatting elements at the position of
+                               // the aforementioned bookmark.
+                               $afe->remove( $fmtelt );
+                               $afe->replace( $BOOKMARK, $newelt2 );
+
+                               // Remove the formatting element from the stack of open
+                               // elements, and insert the new element into the stack of
+                               // open elements immediately below the position of the
+                               // furthest block in that stack.
+                               $this->removeElement( $fmtelt );
+                               $this->insertAfter( $furthestblock, $newelt2 );
+                       }
+               }
+
+               return true;
+       }
+
+       /**
+        * Return the contents of the open elements stack as a string for
+        * debugging.
+        * @return string
+        */
+       public function __toString() {
+               $r = [];
+               foreach ( $this->elements as $elt ) {
+                       array_push( $r, $elt->localName );
+               }
+               return implode( $r, ' ' );
+       }
+}
+
+/**
+ * A pseudo-element used as a marker in the list of active formatting elements
+ *
+ * @ingroup Parser
+ * @since 1.27
+ */
+class BalanceMarker {
+       public $nextAFE;
+       public $prevAFE;
+}
+
+/**
+ * The list of active formatting elements, which is used to handle
+ * mis-nested formatting element tags in the HTML5 tree builder
+ * specification.
+ *
+ * @ingroup Parser
+ * @since 1.27
+ * @see https://html.spec.whatwg.org/multipage/syntax.html#list-of-active-formatting-elements
+ */
+class BalanceActiveFormattingElements {
+       /** The last (most recent) element in the list */
+       private $tail;
+
+       /** The first (least recent) element in the list */
+       private $head;
+
+       /**
+        * An array of arrays representing the population of elements in each bucket
+        * according to the Noah's Ark clause. The outer array is stack-like, with each
+        * integer-indexed element representing a segment of the list, bounded by
+        * markers. The first element represents the segment of the list before the
+        * first marker.
+        *
+        * The inner arrays are indexed by "Noah key", which is a string which uniquely
+        * identifies each bucket according to the rules in the spec. The value in
+        * the inner array is the first (least recently inserted) element in the bucket,
+        * and subsequent members of the bucket can be found by iterating through the
+        * singly-linked list via $node->nextNoah.
+        *
+        * This is optimised for the most common case of inserting into a bucket
+        * with zero members, and deleting a bucket containing one member. In the
+        * worst case, iteration through the list is still O(1) in the document
+        * size, since each bucket can have at most 3 members.
+        */
+       private $noahTableStack = [ [] ];
+
+       public function __destruct() {
+               for ( $node = $this->head; $node; $node = $next ) {
+                       $next = $node->nextAFE;
+                       $node->prevAFE = $node->nextAFE = $node->nextNoah = null;
+               }
+               $this->head = $this->tail = $this->noahTableStack = null;
+       }
+
+       public function insertMarker() {
+               $elt = new BalanceMarker;
+               if ( $this->tail ) {
+                       $this->tail->nextAFE = $elt;
+                       $elt->prevAFE = $this->tail;
+               } else {
+                       $this->head = $elt;
+               }
+               $this->tail = $elt;
+               $this->noahTableStack[] = [];
+       }
+
+       /**
+        * Follow the steps required when the spec requires us to "push onto the
+        * list of active formatting elements".
+        * @param BalanceElement $elt
+        */
+       public function push( BalanceElement $elt ) {
+               // Must not be in the list already
+               if ( $elt->prevAFE !== null || $this->head === $elt ) {
+                       throw new ParameterAssertionException( '$elt',
+                               'Cannot insert a node into the AFE list twice' );
+               }
+
+               // "Noah's Ark clause" -- if there are already three copies of
+               // this element before we encounter a marker, then drop the last
+               // one.
+               $noahKey = $elt->getNoahKey();
+               $table =& $this->noahTableStack[ count( $this->noahTableStack ) - 1 ];
+               if ( !isset( $table[$noahKey] ) ) {
+                       $table[$noahKey] = $elt;
+               } else {
+                       $count = 1;
+                       $head = $tail = $table[$noahKey];
+                       while ( $tail->nextNoah ) {
+                               $tail = $tail->nextNoah;
+                               $count++;
+                       }
+                       if ( $count >= 3 ) {
+                               $this->remove( $head );
+                       }
+                       $tail->nextNoah = $elt;
+               }
+               // Add to the main AFE list
+               if ( $this->tail ) {
+                       $this->tail->nextAFE = $elt;
+                       $elt->prevAFE = $this->tail;
+               } else {
+                       $this->head = $elt;
+               }
+               $this->tail = $elt;
+       }
+
+       /**
+        * Follow the steps required when the spec asks us to "clear the list of
+        * active formatting elements up to the last marker".
+        */
+       public function clearToMarker() {
+               // Iterate back through the list starting from the tail
+               $tail = $this->tail;
+               while ( $tail && !( $tail instanceof BalanceMarker ) ) {
+                       // Unlink the element
+                       $prev = $tail->prevAFE;
+                       $tail->prevAFE = null;
+                       if ( $prev ) {
+                               $prev->nextAFE = null;
+                       }
+                       $tail->nextNoah = null;
+                       $tail = $prev;
+               }
+               // If we finished on a marker, unlink it and pop it off the Noah table stack
+               if ( $tail ) {
+                       $prev = $tail->prevAFE;
+                       if ( $prev ) {
+                               $prev->nextAFE = null;
+                       }
+                       $tail = $prev;
+                       array_pop( $this->noahTableStack );
+               } else {
+                       // No marker: wipe the top-level Noah table (which is the only one)
+                       $this->noahTableStack[0] = [];
+               }
+               // If we removed all the elements, clear the head pointer
+               if ( !$tail ) {
+                       $this->head = null;
+               }
+               $this->tail = $tail;
+       }
+
+       /**
+        * Find and return the last element with the specified tag between the
+        * end of the list and the last marker on the list.
+        * Used when parsing &lt;a&gt; "in body mode".
+        */
+       public function findElementByTag( $tag ) {
+               $elt = $this->tail;
+               while ( $elt && !( $elt instanceof BalanceMarker ) ) {
+                       if ( $elt->localName === $tag ) {
+                               return $elt;
+                       }
+                       $elt = $elt->prevAFE;
+               }
+               return null;
+       }
+
+       /**
+        * Determine whether an element is in the list of formatting elements.
+        * @return boolean
+        */
+       public function isInList( BalanceElement $elt ) {
+               return $this->head === $elt || $elt->prevAFE;
+       }
+
+       /**
+        * Find the element $elt in the list and remove it.
+        * Used when parsing &lt;a&gt; in body mode.
+        */
+       public function remove( BalanceElement $elt ) {
+               if ( $this->head !== $elt && !$elt->prevAFE ) {
+                       throw new ParameterAssertionException( '$elt',
+                               "Attempted to remove an element which is not in the AFE list" );
+               }
+               // Update head and tail pointers
+               if ( $this->head === $elt ) {
+                       $this->head = $elt->nextAFE;
+               }
+               if ( $this->tail === $elt ) {
+                       $this->tail = $elt->prevAFE;
+               }
+               // Update previous element
+               if ( $elt->prevAFE ) {
+                       $elt->prevAFE->nextAFE = $elt->nextAFE;
+               }
+               // Update next element
+               if ( $elt->nextAFE ) {
+                       $elt->nextAFE->prevAFE = $elt->prevAFE;
+               }
+               // Clear pointers so that isInList() etc. will work
+               $elt->prevAFE = $elt->nextAFE = null;
+               // Update Noah list
+               $this->removeFromNoahList( $elt );
+       }
+
+       private function addToNoahList( BalanceElement $elt ) {
+               $noahKey = $elt->getNoahKey();
+               $table =& $this->noahTableStack[ count( $this->noahTableStack ) - 1 ];
+               if ( !isset( $table[$noahKey] ) ) {
+                       $table[$noahKey] = $elt;
+               } else {
+                       $tail = $table[$noahKey];
+                       while ( $tail->nextNoah ) {
+                               $tail = $tail->nextNoah;
+                       }
+                       $tail->nextNoah = $elt;
+               }
+       }
+
+       private function removeFromNoahList( BalanceElement $elt ) {
+               $table =& $this->noahTableStack[ count( $this->noahTableStack ) - 1 ];
+               $key = $elt->getNoahKey();
+               $noahElt = $table[$key];
+               if ( $noahElt === $elt ) {
+                       if ( $noahElt->nextNoah ) {
+                               $table[$key] = $noahElt->nextNoah;
+                               $noahElt->nextNoah = null;
+                       } else {
+                               unset( $table[$key] );
+                       }
+               } else {
+                       do {
+                               $prevNoahElt = $noahElt;
+                               $noahElt = $prevNoahElt->nextNoah;
+                               if ( $noahElt === $elt ) {
+                                       // Found it, unlink
+                                       $prevNoahElt->nextNoah = $elt->nextNoah;
+                                       $elt->nextNoah = null;
+                                       break;
+                               }
+                       } while ( $noahElt );
+               }
+       }
+
+       /**
+        * Find element $a in the list and replace it with element $b
+        */
+       public function replace( BalanceElement $a, BalanceElement $b ) {
+               if ( $this->head !== $a && !$a->prevAFE ) {
+                       throw new ParameterAssertionException( '$a',
+                               "Attempted to replace an element which is not in the AFE list" );
+               }
+               // Update head and tail pointers
+               if ( $this->head === $a ) {
+                       $this->head = $b;
+               }
+               if ( $this->tail === $a ) {
+                       $this->tail = $b;
+               }
+               // Update previous element
+               if ( $a->prevAFE ) {
+                       $a->prevAFE->nextAFE = $b;
+               }
+               // Update next element
+               if ( $a->nextAFE ) {
+                       $a->nextAFE->prevAFE = $b;
+               }
+               $b->prevAFE = $a->prevAFE;
+               $b->nextAFE = $a->nextAFE;
+               $a->nextAFE = $a->prevAFE = null;
+               // Update Noah list
+               $this->removeFromNoahList( $a );
+               $this->addToNoahList( $b );
+       }
+
+       /**
+        * Find $a in the list and insert $b after it.
+        */
+       public function insertAfter( BalanceElement $a, BalanceElement $b ) {
+               if ( $this->head !== $a && !$a->prevAFE ) {
+                       throw new ParameterAssertionException( '$a',
+                               "Attempted to insert after an element which is not in the AFE list" );
+               }
+               if ( $this->tail === $a ) {
+                       $this->tail = $b;
+               }
+               if ( $a->nextAFE ) {
+                       $a->nextAFE->prevAFE = $b;
+               }
+               $b->nextAFE = $a->nextAFE;
+               $b->prevAFE = $a;
+               $a->nextAFE = $b;
+               $this->addToNoahList( $b );
+       }
+
+       // @codingStandardsIgnoreStart Generic.Files.LineLength.TooLong
+       /**
+        * Reconstruct the active formatting elements.
+        * @param BalanceStack $stack The open elements stack
+        * @see https://html.spec.whatwg.org/multipage/syntax.html#reconstruct-the-active-formatting-elements
+        */
+       // @codingStandardsIgnoreEnd
+       public function reconstruct( $stack ) {
+               $entry = $this->tail;
+               // If there are no entries in the list of active formatting elements,
+               // then there is nothing to reconstruct
+               if ( !$entry ) {
+                       return;
+               }
+               // If the last is a marker, do nothing.
+               if ( $entry instanceof BalanceMarker ) {
+                       return;
+               }
+               // Or if it is an open element, do nothing.
+               if ( $stack->indexOf( $entry ) >= 0 ) {
+                       return;
+               }
+
+               // Loop backward through the list until we find a marker or an
+               // open element
+               $foundit = false;
+               while ( $entry->prevAFE ) {
+                       $entry = $entry->prevAFE;
+                       if ( $entry instanceof BalanceMarker || $stack->indexOf( $entry ) >= 0 ) {
+                               $foundit = true;
+                               break;
+                       }
+               }
+
+               // Now loop forward, starting from the element after the current one (or
+               // the first element if we didn't find a marker or open element),
+               // recreating formatting elements and pushing them back onto the list
+               // of open elements.
+               if ( $foundit ) {
+                       $entry = $entry->nextAFE;
+               }
+               do {
+                       $newElement = $stack->insertHTMLElement(
+                               $entry->localName,
+                               $entry->attribs );
+                       $this->replace( $entry, $newElement );
+                       $entry = $newElement->nextAFE;
+               } while ( $entry );
+       }
+
+       /**
+        * Get a string representation of the AFE list, for debugging
+        */
+       public function __toString() {
+               $prev = null;
+               $s = '';
+               for ( $node = $this->head; $node; $prev = $node, $node = $node->nextAFE ) {
+                       if ( $node instanceof BalanceMarker ) {
+                               $s .= "MARKER\n";
+                               continue;
+                       }
+                       $s .= $node->localName . '#' . substr( md5( spl_object_hash( $node ) ), 0, 8 );
+                       if ( $node->nextNoah ) {
+                               $s .= " (noah sibling: {$node->nextNoah->localName}#" .
+                                       substr( md5( spl_object_hash( $node->nextNoah ) ), 0, 8 ) .
+                                       ')';
+                       }
+                       if ( $node->nextAFE && $node->nextAFE->prevAFE !== $node ) {
+                               $s .= " (reverse link is wrong!)";
+                       }
+                       $s .= "\n";
+               }
+               if ( $prev !== $this->tail ) {
+                       $s .= "(tail pointer is wrong!)\n";
+               }
+               return $s;
+       }
+}
+
+/**
+ * An implementation of the tree building portion of the HTML5 parsing
+ * spec.
+ *
+ * This is used to balance and tidy output so that the result can
+ * always be cleanly serialized/deserialized by an HTML5 parser.  It
+ * does *not* guarantee "conforming" output -- the HTML5 spec contains
+ * a number of constraints which are not enforced by the HTML5 parsing
+ * process.  But the result will be free of gross errors: misnested or
+ * unclosed tags, for example, and will be unchanged by spec-complient
+ * parsing followed by serialization.
+ *
+ * The tree building stage is structured as a state machine.
+ * When comparing the implementation to
+ * https://www.w3.org/TR/html5/syntax.html#tree-construction
+ * note that each state is implemented as a function with a
+ * name ending in `Mode` (because the HTML spec refers to them
+ * as insertion modes).  The current insertion mode is held by
+ * the $parseMode property.
+ *
+ * The following simplifications have been made:
+ * - We handle body content only (ie, we start `in body`.)
+ * - The document is never in "quirks mode".
+ * - All occurrences of < and > have been entity escaped, so we
+ *   can parse tags by simply splitting on those two characters.
+ *   (This also simplifies the handling of < inside <textarea>.)
+ *   The character < must not appear inside comments.
+ *   Similarly, all attributes have been "cleaned" and are double-quoted
+ *   and escaped.
+ * - All null characters are assumed to have been removed.
+ * - The following elements are disallowed: <html>, <head>, <body>, <frameset>,
+ *   <frame>, <plaintext>, <isindex>, <xmp>, <iframe>,
+ *   <noembed>, <noscript>, <script>, <title>.  As a result,
+ *   further simplifications can be made:
+ *   - `frameset-ok` is not tracked.
+ *   - `head element pointer` is not tracked (but presumed non-null)
+ *   - Tokenizer has only a single mode. (<textarea> wants RCDATA and
+ *     <style>/<noframes> want RAWTEXT modes which we only loosely emulate.)
+ *
+ *   We generally mark places where we omit cases from the spec due to
+ *   disallowed elements with a comment: `# OMITTED: <element-name>`.
+ *
+ *   The HTML spec keeps a flag during the parsing process to track
+ *   whether or not a "parse error" has been encountered.  We don't
+ *   bother to track that flag, we just implement the error-handling
+ *   process as specified.
+ *
+ * @ingroup Parser
+ * @since 1.27
+ * @see https://html.spec.whatwg.org/multipage/syntax.html#tree-construction
+ */
+class Balancer {
+       private $parseMode;
+       private $bitsIterator;
+       private $allowedHtmlElements;
+       private $afe;
+       private $stack;
+       private $strict;
+       private $tidyCompat;
+       private $allowComments;
+
+       private $textIntegrationMode;
+       private $pendingTableText;
+       private $originalInsertionMode;
+       private $fragmentContext;
+       private $formElementPointer;
+       private $ignoreLinefeed;
+       private $inRCDATA;
+       private $inRAWTEXT;
+
+       /**
+        * Valid HTML5 comments.
+        * Regex borrowed from Tim Starling's "remex-html" project.
+        */
+       const VALID_COMMENT_REGEX = "~ !--
+               (                             # 1. Comment match detector
+                       > | -> | # Invalid short close
+                       (                         # 2. Comment contents
+                               (?:
+                                       (?! --> )
+                                       (?! --!> )
+                                       (?! --! \z )
+                                       (?! -- \z )
+                                       (?! - \z )
+                                       .
+                               )*+
+                       )
+                       (                         # 3. Comment close
+                               --> |   # Normal close
+                               --!> |  # Comment end bang
+                               (                     # 4. Indicate matches requiring EOF
+                                       --! |   # EOF in comment end bang state
+                                       -- |    # EOF in comment end state
+                                       -  |    # EOF in comment end dash state
+                                               # EOF in comment state
+                               )
+                       )
+               )
+               ([^<]*) \z                    # 5. Non-tag text after the comment
+               ~xs";
+
+       /**
+        * Create a new Balancer.
+        * @param array $config Balancer configuration.  Includes:
+        *     'strict' : boolean, defaults to false.
+        *         When true, enforces syntactic constraints on input:
+        *         all non-tag '<' must be escaped, all attributes must be
+        *         separated by a single space and double-quoted.  This is
+        *         consistent with the output of the Sanitizer.
+        *     'allowedHtmlElements' : array, defaults to null.
+        *         When present, the keys of this associative array give
+        *         the acceptable HTML tag names.  When not present, no
+        *         tag sanitization is done.
+        *     'tidyCompat' : boolean, defaults to false.
+        *         When true, the serialization algorithm is tweaked to
+        *         provide historical compatibility with the old "tidy"
+        *         program: <p>-wrapping is done to the children of
+        *         <body> and <blockquote> elements, and empty elements
+        *         are removed.
+        *     'allowComments': boolean, defaults to true.
+        *         When true, allows HTML comments in the input.
+        *         The Sanitizer generally strips all comments, so if you
+        *         are running on sanitized output you can set this to
+        *         false to get a bit more performance.
+        */
+       public function __construct( array $config = [] ) {
+               $config = $config + [
+                       'strict' => false,
+                       'allowedHtmlElements' => null,
+                       'tidyCompat' => false,
+                       'allowComments' => true,
+               ];
+               $this->allowedHtmlElements = $config['allowedHtmlElements'];
+               $this->strict = $config['strict'];
+               $this->tidyCompat = $config['tidyCompat'];
+               $this->allowComments = $config['allowComments'];
+               if ( $this->allowedHtmlElements !== null ) {
+                       # Sanity check!
+                       $bad = array_uintersect_assoc(
+                               $this->allowedHtmlElements,
+                               BalanceSets::$unsupportedSet[BalanceSets::HTML_NAMESPACE],
+                               function( $a, $b ) {
+                                       // Ignore the values (just intersect the keys) by saying
+                                       // all values are equal to each other.
+                                       return 0;
+                               }
+                       );
+                       if ( count( $bad ) > 0 ) {
+                               $badstr = implode( array_keys( $bad ), ',' );
+                               throw new ParameterAssertionException(
+                                       '$config',
+                                       'Balance attempted with sanitization including ' .
+                                       "unsupported elements: {$badstr}"
+                               );
+                       }
+               }
+       }
+
+       /**
+        * Return a balanced HTML string for the HTML fragment given by $text,
+        * subject to the caveats listed in the class description.  The result
+        * will typically be idempotent -- that is, rebalancing the output
+        * would result in no change.
+        *
+        * @param string $text The markup to be balanced
+        * @param callable $processingCallback Callback to do any variable or
+        *   parameter replacements in HTML attributes values
+        * @param array|bool $processingArgs Arguments for the processing callback
+        * @return string The balanced markup
+        */
+       public function balance( $text, $processingCallback = null, $processingArgs = [] ) {
+               $this->parseMode = 'inBodyMode';
+               $this->bitsIterator = new ExplodeIterator( '<', $text );
+               $this->afe = new BalanceActiveFormattingElements();
+               $this->stack = new BalanceStack();
+               $this->stack->tidyCompat = $this->tidyCompat;
+               $this->processingCallback = $processingCallback;
+               $this->processingArgs = $processingArgs;
+
+               $this->textIntegrationMode =
+                       $this->ignoreLinefeed =
+                       $this->inRCDATA =
+                       $this->inRAWTEXT = false;
+
+               # The stack is constructed with an <html> element already on it.
+               # Set this up as a fragment parsed with <body> as the context.
+               $this->fragmentContext =
+                       new BalanceElement( BalanceSets::HTML_NAMESPACE, 'body', [] );
+               $this->resetInsertionMode();
+               $this->formElementPointer = null;
+               for ( $e = $this->fragmentContext; $e != null; $e = $e->parent ) {
+                       if ( $e->isHtmlNamed( 'form' ) ) {
+                               $this->formElementPointer = $e;
+                               break;
+                       }
+               }
+
+               // First element is text not tag
+               $x = $this->bitsIterator->current();
+               $this->bitsIterator->next();
+               $this->insertToken( 'text', str_replace( '>', '&gt;', $x ) );
+               // Now process each tag.
+               while ( $this->bitsIterator->valid() ) {
+                       $this->advance();
+               }
+               $this->insertToken( 'eof', null );
+               $result = $this->stack->getOutput();
+               // Free memory before returning.
+               $this->bitsIterator = null;
+               $this->afe = null;
+               $this->stack = null;
+               $this->fragmentContext = null;
+               $this->formElementPointer = null;
+               return $result;
+       }
+
+       /**
+        * Pass a token to the tree builder.  The $token will be one of the
+        * strings "tag", "endtag", or "text".
+        */
+       private function insertToken( $token, $value, $attribs = null, $selfclose = false ) {
+               // validate tags against $unsupportedSet
+               if ( $token === 'tag' || $token === 'endtag' ) {
+                       if ( isset( BalanceSets::$unsupportedSet[BalanceSets::HTML_NAMESPACE][$value] ) ) {
+                               # As described in "simplifications" above, these tags are
+                               # not supported in the balancer.
+                               Assert::invariant(
+                                       !$this->strict,
+                                       "Unsupported $token <$value> found."
+                               );
+                               return false;
+                       }
+               } elseif ( $token === 'text' && $value === '' ) {
+                       # Don't actually inject the empty string as a text token.
+                       return true;
+               }
+               // Support pre/listing/textarea by suppressing initial linefeed
+               if ( $this->ignoreLinefeed ) {
+                       $this->ignoreLinefeed = false;
+                       if ( $token === 'text' ) {
+                               if ( $value[0] === "\n" ) {
+                                       if ( $value === "\n" ) {
+                                               # Nothing would be left, don't inject the empty string.
+                                               return true;
+                                       }
+                                       $value = substr( $value, 1 );
+                               }
+                       }
+               }
+               // Some hoops we have to jump through
+               $adjusted = $this->stack->adjustedCurrentNode( $this->fragmentContext );
+
+               $isForeign = true;
+               if (
+                       $this->stack->length() === 0 ||
+                       $adjusted->isHtml() ||
+                       $token === 'eof'
+               ) {
+                       $isForeign = false;
+               } elseif ( $adjusted->isMathmlTextIntegrationPoint() ) {
+                       if ( $token === 'text' ) {
+                               $isForeign = false;
+                       } elseif (
+                               $token === 'tag' &&
+                               $value !== 'mglyph' && $value !== 'malignmark'
+                       ) {
+                               $isForeign = false;
+                       }
+               } elseif (
+                       $adjusted->namespaceURI === BalanceSets::MATHML_NAMESPACE &&
+                       $adjusted->localName === 'annotation-xml' &&
+                       $token === 'tag' && $value === 'svg'
+               ) {
+                       $isForeign = false;
+               } elseif (
+                       $adjusted->isHtmlIntegrationPoint() &&
+                       ( $token === 'tag' || $token === 'text' )
+               ) {
+                       $isForeign = false;
+               }
+               if ( $isForeign ) {
+                       return $this->insertForeignToken( $token, $value, $attribs, $selfclose );
+               } else {
+                       $func = $this->parseMode;
+                       return $this->$func( $token, $value, $attribs, $selfclose );
+               }
+       }
+
+       private function insertForeignToken( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' ) {
+                       $this->stack->insertText( $value );
+                       return true;
+               } elseif ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       case 'font':
+                               if ( isset( $attribs['color'] )
+                                       || isset( $attribs['face'] )
+                                       || isset( $attribs['size'] )
+                               ) {
+                                       break;
+                               }
+                               /* otherwise, fall through */
+                       case 'b':
+                       case 'big':
+                       case 'blockquote':
+                       case 'body':
+                       case 'br':
+                       case 'center':
+                       case 'code':
+                       case 'dd':
+                       case 'div':
+                       case 'dl':
+                       case 'dt':
+                       case 'em':
+                       case 'embed':
+                       case 'h1':
+                       case 'h2':
+                       case 'h3':
+                       case 'h4':
+                       case 'h5':
+                       case 'h6':
+                       case 'head':
+                       case 'hr':
+                       case 'i':
+                       case 'img':
+                       case 'li':
+                       case 'listing':
+                       case 'menu':
+                       case 'meta':
+                       case 'nobr':
+                       case 'ol':
+                       case 'p':
+                       case 'pre':
+                       case 'ruby':
+                       case 's':
+                       case 'small':
+                       case 'span':
+                       case 'strong':
+                       case 'strike':
+                       case 'sub':
+                       case 'sup':
+                       case 'table':
+                       case 'tt':
+                       case 'u':
+                       case 'ul':
+                       case 'var':
+                               if ( $this->fragmentContext ) {
+                                       break;
+                               }
+                               while ( true ) {
+                                       $this->stack->pop();
+                                       $node = $this->stack->currentNode;
+                                       if (
+                                               $node->isMathmlTextIntegrationPoint() ||
+                                               $node->isHtmlIntegrationPoint() ||
+                                               $node->isHtml()
+                                       ) {
+                                               break;
+                                       }
+                               }
+                               return $this->insertToken( $token, $value, $attribs, $selfclose );
+                       }
+                       // "Any other start tag"
+                       $adjusted = ( $this->fragmentContext && $this->stack->length()===1 ) ?
+                               $this->fragmentContext : $this->stack->currentNode;
+                       $this->stack->insertForeignElement(
+                               $adjusted->namespaceURI, $value, $attribs
+                       );
+                       if ( $selfclose ) {
+                               $this->stack->pop();
+                       }
+                       return true;
+               } elseif ( $token === 'endtag' ) {
+                       $first = true;
+                       foreach ( $this->stack as $i => $node ) {
+                               if ( $node->isHtml() && !$first ) {
+                                       // process the end tag as HTML
+                                       $func = $this->parseMode;
+                                       return $this->$func( $token, $value, $attribs, $selfclose );
+                               } elseif ( $i === 0 ) {
+                                       return true;
+                               } elseif ( $node->localName === $value ) {
+                                       $this->stack->popTag( $node );
+                                       return true;
+                               }
+                               $first = false;
+                       }
+               }
+       }
+
+       /**
+        * Grab the next "token" from $bitsIterator.  This is either a open/close
+        * tag or text or a comment, depending on whether the Sanitizer approves.
+        */
+       private function advance() {
+               $x = $this->bitsIterator->current();
+               $this->bitsIterator->next();
+               $regs = [];
+               # Handle comments.  These won't be generated by mediawiki (they
+               # are stripped in the Sanitizer) but may be generated by extensions.
+               if (
+                       $this->allowComments &&
+                       !( $this->inRCDATA || $this->inRAWTEXT ) &&
+                       preg_match( Balancer::VALID_COMMENT_REGEX, $x, $regs, PREG_OFFSET_CAPTURE ) &&
+                       /* verify EOF condition where necessary */
+                       ( $regs[4][1] < 0 || !$this->bitsIterator->valid() )
+               ) {
+                       $contents = $regs[2][0];
+                       $rest = $regs[5][0];
+                       $this->insertToken( 'comment', $contents );
+                       $this->insertToken( 'text', str_replace( '>', '&gt;', $rest ) );
+                       return;
+               }
+               # $slash: Does the current element start with a '/'?
+               # $t: Current element name
+               # $attribStr: String between element name and >
+               # $brace: Ending '>' or '/>'
+               # $rest: Everything until the next element from the $bitsIterator
+               if ( preg_match( Sanitizer::ELEMENT_BITS_REGEX, $x, $regs ) ) {
+                       list( /* $qbar */, $slash, $t, $attribStr, $brace, $rest ) = $regs;
+                       $t = strtolower( $t );
+                       if ( $this->strict ) {
+                               /* Verify that attributes are all properly double-quoted */
+                               Assert::invariant(
+                                       preg_match(
+                                               '/^( [:_A-Z0-9][-.:_A-Z0-9]*="[^"]*")*[ ]*$/i', $attribStr
+                                       ),
+                                       "Bad attribute string found"
+                               );
+                       }
+               } else {
+                       Assert::invariant(
+                               !$this->strict, "< found which does not start a valid tag"
+                       );
+                       $slash = $t = $attribStr = $brace = $rest = null;
+               }
+               $goodtag = $t;
+               if ( $this->inRCDATA ) {
+                       if ( $slash && $t === $this->inRCDATA ) {
+                               $this->inRCDATA = false;
+                       } else {
+                               // No tags allowed; this emulates the "rcdata" tokenizer mode.
+                               $goodtag = false;
+                       }
+               }
+               if ( $this->inRAWTEXT ) {
+                       if ( $slash && $t === $this->inRAWTEXT ) {
+                               $this->inRAWTEXT = false;
+                       } else {
+                               // No tags allowed, no entity-escaping done.
+                               $goodtag = false;
+                       }
+               }
+               $sanitize = $this->allowedHtmlElements !== null;
+               if ( $sanitize ) {
+                       $goodtag = $t && isset( $this->allowedHtmlElements[$t] );
+               }
+               if ( $goodtag ) {
+                       if ( is_callable( $this->processingCallback ) ) {
+                               call_user_func_array( $this->processingCallback, [ &$attribStr, $this->processingArgs ] );
+                       }
+                       if ( $sanitize ) {
+                               $goodtag = Sanitizer::validateTag( $attribStr, $t );
+                       }
+               }
+               if ( $goodtag ) {
+                       if ( $sanitize ) {
+                               $attribs = Sanitizer::decodeTagAttributes( $attribStr );
+                               $attribs = Sanitizer::validateTagAttributes( $attribs, $t );
+                       } else {
+                               $attribs = Sanitizer::decodeTagAttributes( $attribStr );
+                       }
+                       $goodtag = $this->insertToken(
+                               $slash ? 'endtag' : 'tag', $t, $attribs, $brace === '/>'
+                       );
+               }
+               if ( $goodtag ) {
+                       $rest = str_replace( '>', '&gt;', $rest );
+                       $this->insertToken( 'text', str_replace( '>', '&gt;', $rest ) );
+               } elseif ( $this->inRAWTEXT ) {
+                       $this->insertToken( 'text', "<$x" );
+               } else {
+                       # bad tag; serialize entire thing as text.
+                       $this->insertToken( 'text', '&lt;' . str_replace( '>', '&gt;', $x ) );
+               }
+       }
+
+       private function switchMode( $mode ) {
+               Assert::parameter(
+                       substr( $mode, -4 )==='Mode', '$mode', 'should end in Mode'
+               );
+               $oldMode = $this->parseMode;
+               $this->parseMode = $mode;
+               return $oldMode;
+       }
+
+       private function switchModeAndReprocess( $mode, $token, $value, $attribs, $selfclose ) {
+               $this->switchMode( $mode );
+               return $this->insertToken( $token, $value, $attribs, $selfclose );
+       }
+
+       private function resetInsertionMode() {
+               $last = false;
+               foreach ( $this->stack as $i => $node ) {
+                       if ( $i === 0 ) {
+                               $last = true;
+                               if ( $this->fragmentContext ) {
+                                       $node = $this->fragmentContext;
+                               }
+                       }
+                       if ( $node->isHtml() ) {
+                               switch ( $node->localName ) {
+                               case 'select':
+                                       $stacklen = $this->stack->length();
+                                       for ( $j = $i + 1; $j < $stacklen-1; $j++ ) {
+                                               $ancestor = $this->stack->node( $stacklen-$j-1 );
+                                               if ( $ancestor->isHtmlNamed( 'template' ) ) {
+                                                       break;
+                                               }
+                                               if ( $ancestor->isHtmlNamed( 'table' ) ) {
+                                                       $this->switchMode( 'inSelectInTableMode' );
+                                                       return;
+                                               }
+                                       }
+                                       $this->switchMode( 'inSelectMode' );
+                                       return;
+                               case 'tr':
+                                       $this->switchMode( 'inRowMode' );
+                                       return;
+                               case 'tbody':
+                               case 'tfoot':
+                               case 'thead':
+                                       $this->switchMode( 'inTableBodyMode' );
+                                       return;
+                               case 'caption':
+                                       $this->switchMode( 'inCaptionMode' );
+                                       return;
+                               case 'colgroup':
+                                       $this->switchMode( 'inColumnGroupMode' );
+                                       return;
+                               case 'table':
+                                       $this->switchMode( 'inTableMode' );
+                                       return;
+                               case 'template':
+                                       $this->switchMode(
+                                               array_slice( $this->templateInsertionModes, -1 )[0]
+                                       );
+                                       return;
+                               case 'body':
+                                       $this->switchMode( 'inBodyMode' );
+                                       return;
+                               # OMITTED: <frameset>
+                               # OMITTED: <html>
+                               # OMITTED: <head>
+                               default:
+                                       if ( !$last ) {
+                                               # OMITTED: <head>
+                                               if ( $node->isA( BalanceSets::$tableCellSet ) ) {
+                                                       $this->switchMode( 'inCellMode' );
+                                                       return;
+                                               }
+                                       }
+                               }
+                       }
+                       if ( $last ) {
+                               $this->switchMode( 'inBodyMode' );
+                               return;
+                       }
+               }
+       }
+
+       private function stopParsing() {
+               # Most of the spec methods are inapplicable, other than step 2:
+               # "pop all the nodes off the stack of open elements".
+               # We're going to keep the top-most <html> element on the stack, though.
+
+               # Clear the AFE list first, otherwise the element objects will stay live
+               # during serialization, potentially using O(N^2) memory. Note that
+               # popping the stack will never result in reconstructing the active
+               # formatting elements.
+               $this->afe = null;
+               $this->stack->popTo( 1 );
+       }
+
+       private function parseRawText( $value, $attribs = null ) {
+               $this->stack->insertHTMLElement( $value, $attribs );
+               $this->inRAWTEXT = $value;
+               $this->originalInsertionMode = $this->switchMode( 'inTextMode' );
+               return true;
+       }
+
+       private function inTextMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' ) {
+                       $this->stack->insertText( $value );
+                       return true;
+               } elseif ( $token === 'eof' ) {
+                       $this->stack->pop();
+                       return $this->switchModeAndReprocess(
+                               $this->originalInsertionMode, $token, $value, $attribs, $selfclose
+                       );
+               } elseif ( $token === 'endtag' ) {
+                       $this->stack->pop();
+                       $this->switchMode( $this->originalInsertionMode );
+                       return true;
+               }
+               return true;
+       }
+
+       private function inHeadMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' ) {
+                       if ( preg_match( '/^[\x09\x0A\x0C\x0D\x20]+/', $value, $matches ) ) {
+                               $this->stack->insertText( $matches[0] );
+                               $value = substr( $value, strlen( $matches[0] ) );
+                       }
+                       if ( strlen( $value ) === 0 ) {
+                               return true; // All text handled.
+                       }
+                       // Fall through to handle non-whitespace below.
+               } elseif ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       case 'meta':
+                               # OMITTED: in a full HTML parser, this might change the encoding.
+                               /* falls through */
+                       # OMITTED: <html>
+                       case 'base':
+                       case 'basefont':
+                       case 'bgsound':
+                       case 'link':
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->stack->pop();
+                               return true;
+                       # OMITTED: <title>
+                       # OMITTED: <noscript>
+                       case 'noframes':
+                       case 'style':
+                               return $this->parseRawText( $value, $attribs );
+                       # OMITTED: <script>
+                       case 'template':
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->afe->insertMarker();
+                               # OMITTED: frameset_ok
+                               $this->switchMode( 'inTemplateMode' );
+                               $this->templateInsertionModes[] = $this->parseMode;
+                               return true;
+                       # OMITTED: <head>
+                       }
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       # OMITTED: <head>
+                       # OMITTED: <body>
+                       # OMITTED: <html>
+                       case 'br':
+                               break; // handle at the bottom of the function
+                       case 'template':
+                               if ( $this->stack->indexOf( $value ) < 0 ) {
+                                       return true; // Ignore the token.
+                               }
+                               $this->stack->generateImpliedEndTags( null, true /* thorough */ );
+                               $this->stack->popTag( $value );
+                               $this->afe->clearToMarker();
+                               array_pop( $this->templateInsertionModes );
+                               $this->resetInsertionMode();
+                               return true;
+                       default:
+                               // ignore any other end tag
+                               return true;
+                       }
+               } elseif ( $token === 'comment' ) {
+                       $this->stack->insertComment( $value );
+                       return true;
+               }
+
+               // If not handled above
+               $this->inHeadMode( 'endtag', 'head' ); // synthetic </head>
+               // Then redo this one
+               return $this->insertToken( $token, $value, $attribs, $selfclose );
+       }
+
+       private function inBodyMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' ) {
+                       $this->afe->reconstruct( $this->stack );
+                       $this->stack->insertText( $value );
+                       return true;
+               } elseif ( $token === 'eof' ) {
+                       if ( !empty( $this->templateInsertionModes ) ) {
+                               return $this->inTemplateMode( $token, $value, $attribs, $selfclose );
+                       }
+                       $this->stopParsing();
+                       return true;
+               } elseif ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       # OMITTED: <html>
+                       case 'base':
+                       case 'basefont':
+                       case 'bgsound':
+                       case 'link':
+                       case 'meta':
+                       case 'noframes':
+                       # OMITTED: <script>
+                       case 'style':
+                       case 'template':
+                       # OMITTED: <title>
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+                       # OMITTED: <body>
+                       # OMITTED: <frameset>
+
+                       case 'address':
+                       case 'article':
+                       case 'aside':
+                       case 'blockquote':
+                       case 'center':
+                       case 'details':
+                       case 'dialog':
+                       case 'dir':
+                       case 'div':
+                       case 'dl':
+                       case 'fieldset':
+                       case 'figcaption':
+                       case 'figure':
+                       case 'footer':
+                       case 'header':
+                       case 'hgroup':
+                       case 'main':
+                       case 'menu':
+                       case 'nav':
+                       case 'ol':
+                       case 'p':
+                       case 'section':
+                       case 'summary':
+                       case 'ul':
+                               if ( $this->stack->inButtonScope( 'p' ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
+                       case 'h1':
+                       case 'h2':
+                       case 'h3':
+                       case 'h4':
+                       case 'h5':
+                       case 'h6':
+                               if ( $this->stack->inButtonScope( 'p' ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               if ( $this->stack->currentNode->isA( BalanceSets::$headingSet ) ) {
+                                       $this->stack->pop();
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
+                       case 'pre':
+                       case 'listing':
+                               if ( $this->stack->inButtonScope( 'p' ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->ignoreLinefeed = true;
+                               # OMITTED: frameset_ok
+                               return true;
+
+                       case 'form':
+                               if (
+                                       $this->formElementPointer &&
+                                       $this->stack->indexOf( 'template' ) < 0
+                               ) {
+                                       return true; // in a form, not in a template.
+                               }
+                               if ( $this->stack->inButtonScope( "p" ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               $elt = $this->stack->insertHTMLElement( $value, $attribs );
+                               if ( $this->stack->indexOf( 'template' ) < 0 ) {
+                                       $this->formElementPointer = $elt;
+                               }
+                               return true;
+
+                       case 'li':
+                               # OMITTED: frameset_ok
+                               foreach ( $this->stack as $node ) {
+                                       if ( $node->isHtmlNamed( 'li' ) ) {
+                                               $this->inBodyMode( 'endtag', 'li' );
+                                               break;
+                                       }
+                                       if (
+                                               $node->isA( BalanceSets::$specialSet ) &&
+                                               !$node->isA( BalanceSets::$addressDivPSet )
+                                       ) {
+                                               break;
+                                       }
+                               }
+                               if ( $this->stack->inButtonScope( 'p' ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
+                       case 'dd':
+                       case 'dt':
+                               # OMITTED: frameset_ok
+                               foreach ( $this->stack as $node ) {
+                                       if ( $node->isHtmlNamed( 'dd' ) ) {
+                                               $this->inBodyMode( 'endtag', 'dd' );
+                                               break;
+                                       }
+                                       if ( $node->isHtmlNamed( 'dt' ) ) {
+                                               $this->inBodyMode( 'endtag', 'dt' );
+                                               break;
+                                       }
+                                       if (
+                                               $node->isA( BalanceSets::$specialSet ) &&
+                                               !$node->isA( BalanceSets::$addressDivPSet )
+                                       ) {
+                                               break;
+                                       }
+                               }
+                               if ( $this->stack->inButtonScope( 'p' ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
+                       # OMITTED: <plaintext>
+
+                       case 'button':
+                               if ( $this->stack->inScope( 'button' ) ) {
+                                       $this->inBodyMode( 'endtag', 'button' );
+                                       return $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               $this->afe->reconstruct( $this->stack );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
+                       case 'a':
+                               $activeElement = $this->afe->findElementByTag( 'a' );
+                               if ( $activeElement ) {
+                                       $this->inBodyMode( 'endtag', 'a' );
+                                       if ( $this->afe->isInList( $activeElement ) ) {
+                                               $this->afe->remove( $activeElement );
+                                               // Don't flatten here, since when we fall
+                                               // through below we might foster parent
+                                               // the new <a> tag inside this one.
+                                               $this->stack->removeElement( $activeElement, false );
+                                       }
+                               }
+                               /* Falls through */
+                       case 'b':
+                       case 'big':
+                       case 'code':
+                       case 'em':
+                       case 'font':
+                       case 'i':
+                       case 's':
+                       case 'small':
+                       case 'strike':
+                       case 'strong':
+                       case 'tt':
+                       case 'u':
+                               $this->afe->reconstruct( $this->stack );
+                               $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ), $attribs );
+                               return true;
+
+                       case 'nobr':
+                               $this->afe->reconstruct( $this->stack );
+                               if ( $this->stack->inScope( 'nobr' ) ) {
+                                       $this->inBodyMode( 'endtag', 'nobr' );
+                                       $this->afe->reconstruct( $this->stack );
+                               }
+                               $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ), $attribs );
+                               return true;
+
+                       case 'applet':
+                       case 'marquee':
+                       case 'object':
+                               $this->afe->reconstruct( $this->stack );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->afe->insertMarker();
+                               # OMITTED: frameset_ok
+                               return true;
+
+                       case 'table':
+                               # The document is never in "quirks mode"; see simplifications
+                               # above.
+                               if ( $this->stack->inButtonScope( 'p' ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               # OMITTED: frameset_ok
+                               $this->switchMode( 'inTableMode' );
+                               return true;
+
+                       case 'area':
+                       case 'br':
+                       case 'embed':
+                       case 'img':
+                       case 'keygen':
+                       case 'wbr':
+                               $this->afe->reconstruct( $this->stack );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->stack->pop();
+                               # OMITTED: frameset_ok
+                               return true;
+
+                       case 'input':
+                               $this->afe->reconstruct( $this->stack );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->stack->pop();
+                               # OMITTED: frameset_ok
+                               # (hence we don't need to examine the tag's "type" attribute)
+                               return true;
+
+                       case 'menuitem':
+                       case 'param':
+                       case 'source':
+                       case 'track':
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->stack->pop();
+                               return true;
+
+                       case 'hr':
+                               if ( $this->stack->inButtonScope( 'p' ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->stack->pop();
+                               return true;
+
+                       case 'image':
+                               # warts!
+                               return $this->inBodyMode( $token, 'img', $attribs, $selfclose );
+
+                       # OMITTED: <isindex>
+
+                       case 'textarea':
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->ignoreLinefeed = true;
+                               $this->inRCDATA = $value; // emulate rcdata tokenizer mode
+                               # OMITTED: frameset_ok
+                               return true;
+
+                       # OMITTED: <xmp>
+                       # OMITTED: <iframe>
+                       # OMITTED: <noembed>
+                       # OMITTED: <noscript>
+
+                       case 'select':
+                               $this->afe->reconstruct( $this->stack );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               switch ( $this->parseMode ) {
+                               case 'inTableMode':
+                               case 'inCaptionMode':
+                               case 'inTableBodyMode':
+                               case 'inRowMode':
+                               case 'inCellMode':
+                                       $this->switchMode( 'inSelectInTableMode' );
+                                       return true;
+                               default:
+                                       $this->switchMode( 'inSelectMode' );
+                                       return true;
+                               }
+
+                       case 'optgroup':
+                       case 'option':
+                               if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
+                                       $this->inBodyMode( 'endtag', 'option' );
+                               }
+                               $this->afe->reconstruct( $this->stack );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
+                       case 'rb':
+                       case 'rtc':
+                               if ( $this->stack->inScope( 'ruby' ) ) {
+                                       $this->stack->generateImpliedEndTags();
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
+                       case 'rp':
+                       case 'rt':
+                               if ( $this->stack->inScope( 'ruby' ) ) {
+                                       $this->stack->generateImpliedEndTags( 'rtc' );
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
+                       case 'math':
+                               $this->afe->reconstruct( $this->stack );
+                               # We skip the spec's "adjust MathML attributes" and
+                               # "adjust foreign attributes" steps, since the browser will
+                               # do this later when it parses the output and it doesn't affect
+                               # balancing.
+                               $this->stack->insertForeignElement(
+                                       BalanceSets::MATHML_NAMESPACE, $value, $attribs
+                               );
+                               if ( $selfclose ) {
+                                       # emit explicit </math> tag.
+                                       $this->stack->pop();
+                               }
+                               return true;
+
+                       case 'svg':
+                               $this->afe->reconstruct( $this->stack );
+                               # We skip the spec's "adjust SVG attributes" and
+                               # "adjust foreign attributes" steps, since the browser will
+                               # do this later when it parses the output and it doesn't affect
+                               # balancing.
+                               $this->stack->insertForeignElement(
+                                       BalanceSets::SVG_NAMESPACE, $value, $attribs
+                               );
+                               if ( $selfclose ) {
+                                       # emit explicit </svg> tag.
+                                       $this->stack->pop();
+                               }
+                               return true;
+
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       # OMITTED: <frame>
+                       case 'head':
+                       case 'tbody':
+                       case 'td':
+                       case 'tfoot':
+                       case 'th':
+                       case 'thead':
+                       case 'tr':
+                               // Ignore table tags if we're not inTableMode
+                               return true;
+                       }
+
+                       // Handle any other start tag here
+                       $this->afe->reconstruct( $this->stack );
+                       $this->stack->insertHTMLElement( $value, $attribs );
+                       return true;
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       # </body>,</html> are unsupported.
+
+                       case 'template':
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+
+                       case 'address':
+                       case 'article':
+                       case 'aside':
+                       case 'blockquote':
+                       case 'button':
+                       case 'center':
+                       case 'details':
+                       case 'dialog':
+                       case 'dir':
+                       case 'div':
+                       case 'dl':
+                       case 'fieldset':
+                       case 'figcaption':
+                       case 'figure':
+                       case 'footer':
+                       case 'header':
+                       case 'hgroup':
+                       case 'listing':
+                       case 'main':
+                       case 'menu':
+                       case 'nav':
+                       case 'ol':
+                       case 'pre':
+                       case 'section':
+                       case 'summary':
+                       case 'ul':
+                               // Ignore if there is not a matching open tag
+                               if ( !$this->stack->inScope( $value ) ) {
+                                       return true;
+                               }
+                               $this->stack->generateImpliedEndTags();
+                               $this->stack->popTag( $value );
+                               return true;
+
+                       case 'form':
+                               if ( $this->stack->indexOf( 'template' ) < 0 ) {
+                                       $openform = $this->formElementPointer;
+                                       $this->formElementPointer = null;
+                                       if ( !$openform || !$this->stack->inScope( $openform ) ) {
+                                               return true;
+                                       }
+                                       $this->stack->generateImpliedEndTags();
+                                       // Don't flatten yet if we're removing a <form> element
+                                       // out-of-order. (eg. `<form><div></form>`)
+                                       $flatten = ( $this->stack->currentNode === $openform );
+                                       $this->stack->removeElement( $openform, $flatten );
+                               } else {
+                                       if ( !$this->stack->inScope( 'form' ) ) {
+                                               return true;
+                                       }
+                                       $this->stack->generateImpliedEndTags();
+                                       $this->stack->popTag( 'form' );
+                               }
+                               return true;
+
+                       case 'p':
+                               if ( !$this->stack->inButtonScope( 'p' ) ) {
+                                       $this->inBodyMode( 'tag', 'p', [] );
+                                       return $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               $this->stack->generateImpliedEndTags( $value );
+                               $this->stack->popTag( $value );
+                               return true;
+
+                       case 'li':
+                               if ( !$this->stack->inListItemScope( $value ) ) {
+                                       return true; # ignore
+                               }
+                               $this->stack->generateImpliedEndTags( $value );
+                               $this->stack->popTag( $value );
+                               return true;
+
+                       case 'dd':
+                       case 'dt':
+                               if ( !$this->stack->inScope( $value ) ) {
+                                       return true; # ignore
+                               }
+                               $this->stack->generateImpliedEndTags( $value );
+                               $this->stack->popTag( $value );
+                               return true;
+
+                       case 'h1':
+                       case 'h2':
+                       case 'h3':
+                       case 'h4':
+                       case 'h5':
+                       case 'h6':
+                               if ( !$this->stack->inScope( BalanceSets::$headingSet ) ) {
+                                       return true; # ignore
+                               }
+                               $this->stack->generateImpliedEndTags();
+                               $this->stack->popTag( BalanceSets::$headingSet );
+                               return true;
+
+                       case 'sarcasm':
+                               # Take a deep breath, then:
+                               break;
+
+                       case 'a':
+                       case 'b':
+                       case 'big':
+                       case 'code':
+                       case 'em':
+                       case 'font':
+                       case 'i':
+                       case 'nobr':
+                       case 's':
+                       case 'small':
+                       case 'strike':
+                       case 'strong':
+                       case 'tt':
+                       case 'u':
+                               if ( $this->stack->adoptionAgency( $value, $this->afe ) ) {
+                                       return true; # If we did something, we're done.
+                               }
+                               break; # Go to the "any other end tag" case.
+
+                       case 'applet':
+                       case 'marquee':
+                       case 'object':
+                               if ( !$this->stack->inScope( $value ) ) {
+                                       return true; # ignore
+                               }
+                               $this->stack->generateImpliedEndTags();
+                               $this->stack->popTag( $value );
+                               $this->afe->clearToMarker();
+                               return true;
+
+                       case 'br':
+                               # Turn </br> into <br>
+                               return $this->inBodyMode( 'tag', $value, [] );
+                       }
+
+                       // Any other end tag goes here
+                       foreach ( $this->stack as $i => $node ) {
+                               if ( $node->isHtmlNamed( $value ) ) {
+                                       $this->stack->generateImpliedEndTags( $value );
+                                       $this->stack->popTo( $i ); # including $i
+                                       break;
+                               } elseif ( $node->isA( BalanceSets::$specialSet ) ) {
+                                       return true; // ignore this close token.
+                               }
+                       }
+                       return true;
+               } elseif ( $token === 'comment' ) {
+                       $this->stack->insertComment( $value );
+                       return true;
+               } else {
+                       Assert::invariant( false, "Bad token type: $token" );
+               }
+       }
+
+       private function inTableMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' ) {
+                       if ( $this->textIntegrationMode ) {
+                               return $this->inBodyMode( $token, $value, $attribs, $selfclose );
+                       } elseif ( $this->stack->currentNode->isA( BalanceSets::$tableSectionRowSet ) ) {
+                               $this->pendingTableText = '';
+                               $this->originalInsertionMode = $this->parseMode;
+                               return $this->switchModeAndReprocess( 'inTableTextMode', $token, $value, $attribs, $selfclose );
+                       }
+                       // fall through to default case.
+               } elseif ( $token === 'eof' ) {
+                       $this->stopParsing();
+                       return true;
+               } elseif ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       case 'caption':
+                               $this->afe->insertMarker();
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->switchMode( 'inCaptionMode' );
+                               return true;
+                       case 'colgroup':
+                               $this->stack->clearToContext( BalanceSets::$tableContextSet );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->switchMode( 'inColumnGroupMode' );
+                               return true;
+                       case 'col':
+                               $this->inTableMode( 'tag', 'colgroup', [] );
+                               return $this->insertToken( $token, $value, $attribs, $selfclose );
+                       case 'tbody':
+                       case 'tfoot':
+                       case 'thead':
+                               $this->stack->clearToContext( BalanceSets::$tableContextSet );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->switchMode( 'inTableBodyMode' );
+                               return true;
+                       case 'td':
+                       case 'th':
+                       case 'tr':
+                               $this->inTableMode( 'tag', 'tbody', [] );
+                               return $this->insertToken( $token, $value, $attribs, $selfclose );
+                       case 'table':
+                               if ( !$this->stack->inTableScope( $value ) ) {
+                                       return true; // Ignore this tag.
+                               }
+                               $this->inTableMode( 'endtag', $value );
+                               return $this->insertToken( $token, $value, $attribs, $selfclose );
+
+                       case 'style':
+                       # OMITTED: <script>
+                       case 'template':
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+
+                       case 'input':
+                               if ( !isset( $attribs['type'] ) || strcasecmp( $attribs['type'], 'hidden' ) !== 0 ) {
+                                       break; // Handle this as "everything else"
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->stack->pop();
+                               return true;
+
+                       case 'form':
+                               if (
+                                       $this->formElementPointer ||
+                                       $this->stack->indexOf( 'template' ) >= 0
+                               ) {
+                                       return true; // ignore this token
+                               }
+                               $this->formElementPointer =
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->stack->popTag( $this->formElementPointer );
+                               return true;
+                       }
+                       // Fall through for "anything else" clause.
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       case 'table':
+                               if ( !$this->stack->inTableScope( $value ) ) {
+                                       return true; // Ignore.
+                               }
+                               $this->stack->popTag( $value );
+                               $this->resetInsertionMode();
+                               return true;
+                       # OMITTED: <body>
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       # OMITTED: <html>
+                       case 'tbody':
+                       case 'td':
+                       case 'tfoot':
+                       case 'th':
+                       case 'thead':
+                       case 'tr':
+                               return true; // Ignore the token.
+                       case 'template':
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+                       }
+                       // Fall through for "anything else" clause.
+               } elseif ( $token === 'comment' ) {
+                       $this->stack->insertComment( $value );
+                       return true;
+               }
+               // This is the "anything else" case:
+               $this->stack->fosterParentMode = true;
+               $this->inBodyMode( $token, $value, $attribs, $selfclose );
+               $this->stack->fosterParentMode = false;
+               return true;
+       }
+
+       private function inTableTextMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' ) {
+                       $this->pendingTableText .= $value;
+                       return true;
+               }
+               // Non-text token:
+               $text = $this->pendingTableText;
+               $this->pendingTableText = '';
+               if ( preg_match( '/[^\x09\x0A\x0C\x0D\x20]/', $text ) ) {
+                       // This should match the "anything else" case inTableMode
+                       $this->stack->fosterParentMode = true;
+                       $this->inBodyMode( 'text', $text );
+                       $this->stack->fosterParentMode = false;
+               } else {
+                       // Pending text is just whitespace.
+                       $this->stack->insertText( $text );
+               }
+               return $this->switchModeAndReprocess(
+                       $this->originalInsertionMode, $token, $value, $attribs, $selfclose
+               );
+       }
+
+       // helper for inCaptionMode
+       private function endCaption() {
+               if ( !$this->stack->inTableScope( 'caption' ) ) {
+                       return false;
+               }
+               $this->stack->generateImpliedEndTags();
+               $this->stack->popTag( 'caption' );
+               $this->afe->clearToMarker();
+               $this->switchMode( 'inTableMode' );
+               return true;
+       }
+
+       private function inCaptionMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       case 'tbody':
+                       case 'td':
+                       case 'tfoot':
+                       case 'th':
+                       case 'thead':
+                       case 'tr':
+                               if ( $this->endCaption() ) {
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       }
+                       // Fall through to "anything else" case.
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       case 'caption':
+                               $this->endCaption();
+                               return true;
+                       case 'table':
+                               if ( $this->endCaption() ) {
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       case 'body':
+                       case 'col':
+                       case 'colgroup':
+                       # OMITTED: <html>
+                       case 'tbody':
+                       case 'td':
+                       case 'tfoot':
+                       case 'th':
+                       case 'thead':
+                       case 'tr':
+                               // Ignore the token
+                               return true;
+                       }
+                       // Fall through to "anything else" case.
+               }
+               // The Anything Else case
+               return $this->inBodyMode( $token, $value, $attribs, $selfclose );
+       }
+
+       private function inColumnGroupMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' ) {
+                       if ( preg_match( '/^[\x09\x0A\x0C\x0D\x20]+/', $value, $matches ) ) {
+                               $this->stack->insertText( $matches[0] );
+                               $value = substr( $value, strlen( $matches[0] ) );
+                       }
+                       if ( strlen( $value ) === 0 ) {
+                               return true; // All text handled.
+                       }
+                       // Fall through to handle non-whitespace below.
+               } elseif ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       # OMITTED: <html>
+                       case 'col':
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->stack->pop();
+                               return true;
+                       case 'template':
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+                       }
+                       // Fall through for "anything else".
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       case 'colgroup':
+                               if ( !$this->stack->currentNode->isHtmlNamed( 'colgroup' ) ) {
+                                       return true; // Ignore the token.
+                               }
+                               $this->stack->pop();
+                               $this->switchMode( 'inTableMode' );
+                               return true;
+                       case 'col':
+                               return true; // Ignore the token.
+                       case 'template':
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+                       }
+                       // Fall through for "anything else".
+               } elseif ( $token === 'eof' ) {
+                       return $this->inBodyMode( $token, $value, $attribs, $selfclose );
+               } elseif ( $token === 'comment' ) {
+                       $this->stack->insertComment( $value );
+                       return true;
+               }
+
+               // Anything else
+               if ( !$this->stack->currentNode->isHtmlNamed( 'colgroup' ) ) {
+                       return true; // Ignore the token.
+               }
+               $this->inColumnGroupMode( 'endtag', 'colgroup' );
+               return $this->insertToken( $token, $value, $attribs, $selfclose );
+       }
+
+       // Helper function for inTableBodyMode
+       private function endSection() {
+               if ( !(
+                       $this->stack->inTableScope( 'tbody' ) ||
+                       $this->stack->inTableScope( 'thead' ) ||
+                       $this->stack->inTableScope( 'tfoot' )
+               ) ) {
+                       return false;
+               }
+               $this->stack->clearToContext( BalanceSets::$tableBodyContextSet );
+               $this->stack->pop();
+               $this->switchMode( 'inTableMode' );
+               return true;
+       }
+       private function inTableBodyMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       case 'tr':
+                               $this->stack->clearToContext( BalanceSets::$tableBodyContextSet );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->switchMode( 'inRowMode' );
+                               return true;
+                       case 'th':
+                       case 'td':
+                               $this->inTableBodyMode( 'tag', 'tr', [] );
+                               $this->insertToken( $token, $value, $attribs, $selfclose );
+                               return true;
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       case 'tbody':
+                       case 'tfoot':
+                       case 'thead':
+                               if ( $this->endSection() ) {
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       }
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       case 'table':
+                               if ( $this->endSection() ) {
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       case 'tbody':
+                       case 'tfoot':
+                       case 'thead':
+                               if ( $this->stack->inTableScope( $value ) ) {
+                                       $this->endSection();
+                               }
+                               return true;
+                       # OMITTED: <body>
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       # OMITTED: <html>
+                       case 'td':
+                       case 'th':
+                       case 'tr':
+                               return true; // Ignore the token.
+                       }
+               }
+               // Anything else:
+               return $this->inTableMode( $token, $value, $attribs, $selfclose );
+       }
+
+       // Helper function for inRowMode
+       private function endRow() {
+               if ( !$this->stack->inTableScope( 'tr' ) ) {
+                       return false;
+               }
+               $this->stack->clearToContext( BalanceSets::$tableRowContextSet );
+               $this->stack->pop();
+               $this->switchMode( 'inTableBodyMode' );
+               return true;
+       }
+       private function inRowMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       case 'th':
+                       case 'td':
+                               $this->stack->clearToContext( BalanceSets::$tableRowContextSet );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               $this->switchMode( 'inCellMode' );
+                               $this->afe->insertMarker();
+                               return true;
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       case 'tbody':
+                       case 'tfoot':
+                       case 'thead':
+                       case 'tr':
+                               if ( $this->endRow() ) {
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       }
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       case 'tr':
+                               $this->endRow();
+                               return true;
+                       case 'table':
+                               if ( $this->endRow() ) {
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       case 'tbody':
+                       case 'tfoot':
+                       case 'thead':
+                               if (
+                                       $this->stack->inTableScope( $value ) &&
+                                       $this->endRow()
+                               ) {
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       # OMITTED: <body>
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       # OMITTED: <html>
+                       case 'td':
+                       case 'th':
+                               return true; // Ignore the token.
+                       }
+               }
+               // Anything else:
+               return $this->inTableMode( $token, $value, $attribs, $selfclose );
+       }
+
+       // Helper for inCellMode
+       private function endCell() {
+               if ( $this->stack->inTableScope( 'td' ) ) {
+                       $this->inCellMode( 'endtag', 'td' );
+                       return true;
+               } elseif ( $this->stack->inTableScope( 'th' ) ) {
+                       $this->inCellMode( 'endtag', 'th' );
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+       private function inCellMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       case 'tbody':
+                       case 'td':
+                       case 'tfoot':
+                       case 'th':
+                       case 'thead':
+                       case 'tr':
+                               if ( $this->endCell() ) {
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       }
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       case 'td':
+                       case 'th':
+                               if ( $this->stack->inTableScope( $value ) ) {
+                                       $this->stack->generateImpliedEndTags();
+                                       $this->stack->popTag( $value );
+                                       $this->afe->clearToMarker();
+                                       $this->switchMode( 'inRowMode' );
+                               }
+                               return true;
+                       # OMITTED: <body>
+                       case 'caption':
+                       case 'col':
+                       case 'colgroup':
+                       # OMITTED: <html>
+                               return true;
+
+                       case 'table':
+                       case 'tbody':
+                       case 'tfoot':
+                       case 'thead':
+                       case 'tr':
+                               if ( $this->stack->inTableScope( $value ) ) {
+                                       $this->stack->generateImpliedEndTags();
+                                       $this->stack->popTag( BalanceSets::$tableCellSet );
+                                       $this->afe->clearToMarker();
+                                       $this->switchMode( 'inRowMode' );
+                                       $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       }
+               }
+               // Anything else:
+               return $this->inBodyMode( $token, $value, $attribs, $selfclose );
+       }
+
+       private function inSelectMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' ) {
+                       $this->stack->insertText( $value );
+                       return true;
+               } elseif ( $token === 'eof' ) {
+                       return $this->inBodyMode( $token, $value, $attribs, $selfclose );
+               } elseif ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       # OMITTED: <html>
+                       case 'option':
+                               if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
+                                       $this->stack->pop();
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+                       case 'optgroup':
+                               if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
+                                       $this->stack->pop();
+                               }
+                               if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) {
+                                       $this->stack->pop();
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+                       case 'select':
+                               $this->inSelectMode( 'endtag', $value ); // treat it like endtag
+                               return true;
+                       case 'input':
+                       case 'keygen':
+                       case 'textarea':
+                               if ( !$this->stack->inSelectScope( 'select' ) ) {
+                                       return true; // ignore token (fragment case)
+                               }
+                               $this->inSelectMode( 'endtag', 'select' );
+                               return $this->insertToken( $token, $value, $attribs, $selfclose );
+                       case 'script':
+                       case 'template':
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+                       }
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       case 'optgroup':
+                               if (
+                                       $this->stack->currentNode->isHtmlNamed( 'option' ) &&
+                                       $this->stack->length() >= 2 &&
+                                       $this->stack->node( $this->stack->length() - 2 )->isHtmlNamed( 'optgroup' )
+                               ) {
+                                       $this->stack->pop();
+                               }
+                               if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) {
+                                       $this->stack->pop();
+                               }
+                               return true;
+                       case 'option':
+                               if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
+                                       $this->stack->pop();
+                               }
+                               return true;
+                       case 'select':
+                               if ( !$this->stack->inSelectScope( $value ) ) {
+                                       return true; // fragment case
+                               }
+                               $this->stack->popTag( $value );
+                               $this->resetInsertionMode();
+                               return true;
+                       case 'template':
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+                       }
+               } elseif ( $token === 'comment' ) {
+                       $this->stack->insertComment( $value );
+                       return true;
+               }
+               // anything else: just ignore the token
+               return true;
+       }
+
+       private function inSelectInTableMode( $token, $value, $attribs = null, $selfclose = false ) {
+               switch ( $value ) {
+               case 'caption':
+               case 'table':
+               case 'tbody':
+               case 'tfoot':
+               case 'thead':
+               case 'tr':
+               case 'td':
+               case 'th':
+                       if ( $token === 'tag' ) {
+                               $this->inSelectInTableMode( 'endtag', 'select' );
+                               return $this->insertToken( $token, $value, $attribs, $selfclose );
+                       } elseif ( $token === 'endtag' ) {
+                               if ( $this->stack->inTableScope( $value ) ) {
+                                       $this->inSelectInTableMode( 'endtag', 'select' );
+                                       return $this->insertToken( $token, $value, $attribs, $selfclose );
+                               }
+                               return true;
+                       }
+               }
+               // anything else
+               return $this->inSelectMode( $token, $value, $attribs, $selfclose );
+       }
+
+       private function inTemplateMode( $token, $value, $attribs = null, $selfclose = false ) {
+               if ( $token === 'text' || $token === 'comment' ) {
+                       return $this->inBodyMode( $token, $value, $attribs, $selfclose );
+               } elseif ( $token === 'eof' ) {
+                       if ( $this->stack->indexOf( 'template' ) < 0 ) {
+                               $this->stopParsing();
+                       } else {
+                               $this->stack->popTag( 'template' );
+                               $this->afe->clearToMarker();
+                               array_pop( $this->templateInsertionModes );
+                               $this->resetInsertionMode();
+                               $this->insertToken( $token, $value, $attribs, $selfclose );
+                       }
+                       return true;
+               } elseif ( $token === 'tag' ) {
+                       switch ( $value ) {
+                       case 'base':
+                       case 'basefont':
+                       case 'bgsound':
+                       case 'link':
+                       case 'meta':
+                       case 'noframes':
+                       # OMITTED: <script>
+                       case 'style':
+                       case 'template':
+                       # OMITTED: <title>
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+
+                       case 'caption':
+                       case 'colgroup':
+                       case 'tbody':
+                       case 'tfoot':
+                       case 'thead':
+                               return $this->switchModeAndReprocess(
+                                       'inTableMode', $token, $value, $attribs, $selfclose
+                               );
+
+                       case 'col':
+                               return $this->switchModeAndReprocess(
+                                       'inColumnGroupMode', $token, $value, $attribs, $selfclose
+                               );
+
+                       case 'tr':
+                               return $this->switchModeAndReprocess(
+                                       'inTableBodyMode', $token, $value, $attribs, $selfclose
+                               );
+
+                       case 'td':
+                       case 'th':
+                               return $this->switchModeAndReprocess(
+                                       'inRowMode', $token, $value, $attribs, $selfclose
+                               );
+                       }
+                       return $this->switchModeAndReprocess(
+                               'inBodyMode', $token, $value, $attribs, $selfclose
+                       );
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                       case 'template':
+                               return $this->inHeadMode( $token, $value, $attribs, $selfclose );
+                       }
+                       return true;
+               } else {
+                       Assert::invariant( false, "Bad token type: $token" );
+               }
+       }
+}
diff --git a/includes/tidy/Html5Internal.php b/includes/tidy/Html5Internal.php
new file mode 100644 (file)
index 0000000..4ad8200
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+namespace MediaWiki\Tidy;
+
+class Html5Internal extends TidyDriverBase {
+       private $balancer;
+       public function __construct( array $config ) {
+               parent::__construct( $config + [
+                       'strict' => true,
+                       'tidyCompat' => true,
+               ] );
+               $this->balancer = new Balancer( $this->config );
+       }
+
+       public function tidy( $text ) {
+               return $this->balancer->balance( $text );
+       }
+}
index ab19142..56d5ce7 100644 (file)
@@ -54,7 +54,7 @@ class RaggettWrapper {
                // Preserve empty li elements (T49673) by abusing Tidy's datafld hack
                // The whitespace class is as in TY_(InitMap)
                $wrappedtext = preg_replace( "!<li>([ \r\n\t\f]*)</li>!",
-                       '<li datafld="" class="mw-empty-li">\1</li>', $wrappedtext );
+                       '<li datafld="" class="mw-empty-elt">\1</li>', $wrappedtext );
 
                // Wrap the whole thing in a doctype and body for Tidy.
                $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' .
index 6dcc948..71d032f 100644 (file)
@@ -467,9 +467,13 @@ abstract class UploadBase {
                        }
                }
 
-               Hooks::run( 'UploadVerifyFile', [ $this, $mime, &$status ] );
-               if ( $status !== true ) {
-                       return $status;
+               $error = true;
+               Hooks::run( 'UploadVerifyFile', [ $this, $mime, &$error ] );
+               if ( $error !== true ) {
+                       if ( !is_array( $error ) ) {
+                               $error = [ $error ];
+                       }
+                       return $error;
                }
 
                wfDebug( __METHOD__ . ": all clear; passing.\n" );
index 4a92f65..a774aba 100644 (file)
@@ -772,15 +772,15 @@ class User implements IDBAccessObject {
                        return self::$idCacheByName[$name];
                }
 
-               $db = ( $flags & self::READ_LATEST )
-                       ? wfGetDB( DB_MASTER )
-                       : wfGetDB( DB_SLAVE );
+               list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $flags );
+               $db = wfGetDB( $index );
 
                $s = $db->selectRow(
                        'user',
                        [ 'user_id' ],
                        [ 'user_name' => $nt->getText() ],
-                       __METHOD__
+                       __METHOD__,
+                       $options
                );
 
                if ( $s === false ) {
index 419ee47..c7bd395 100644 (file)
@@ -31,7 +31,7 @@ class BatchRowIterator implements RecursiveIterator {
        protected $db;
 
        /**
-        * @var string $table The name of the table to read from
+        * @var string|array $table The name or names of the table to read from
         */
        protected $table;
 
@@ -79,7 +79,7 @@ class BatchRowIterator implements RecursiveIterator {
 
        /**
         * @param IDatabase $db The database to read from
-        * @param string       $table      The name of the table to read from
+        * @param string|array $table      The name or names of the table to read from
         * @param string|array $primaryKey The name or names of the primary key columns
         * @param integer      $batchSize  The number of rows to fetch per iteration
         * @throws MWException
index 37f4137..d96710a 100644 (file)
@@ -2577,9 +2577,6 @@ class Language {
         * @return string
         */
        public function iconv( $in, $out, $string ) {
-               # This is a wrapper for iconv in all languages except esperanto,
-               # which does some nasty x-conversions beforehand
-
                # Even with //IGNORE iconv can whine about illegal characters in
                # *input* string. We just ignore those too.
                # REF: http://bugs.php.net/bug.php?id=37166
@@ -2929,46 +2926,29 @@ class Language {
                }
        }
 
+       /**
+        * @deprecated No-op since 1.28
+        */
        function initEncoding() {
-               # Some languages may have an alternate char encoding option
-               # (Esperanto X-coding, Japanese furigana conversion, etc)
-               # If this language is used as the primary content language,
-               # an override to the defaults can be set here on startup.
+               // No-op.
        }
 
        /**
         * @param string $s
         * @return string
+        * @deprecated No-op since 1.28
         */
        function recodeForEdit( $s ) {
-               # For some languages we'll want to explicitly specify
-               # which characters make it into the edit box raw
-               # or are converted in some way or another.
-               global $wgEditEncoding;
-               if ( $wgEditEncoding == '' || $wgEditEncoding == 'UTF-8' ) {
-                       return $s;
-               } else {
-                       return $this->iconv( 'UTF-8', $wgEditEncoding, $s );
-               }
+               return $s;
        }
 
        /**
         * @param string $s
         * @return string
+        * @deprecated No-op since 1.28
         */
        function recodeInput( $s ) {
-               # Take the previous into account.
-               global $wgEditEncoding;
-               if ( $wgEditEncoding != '' ) {
-                       $enc = $wgEditEncoding;
-               } else {
-                       $enc = 'UTF-8';
-               }
-               if ( $enc == 'UTF-8' ) {
-                       return $s;
-               } else {
-                       return $this->iconv( $enc, 'UTF-8', $s );
-               }
+               return $s;
        }
 
        /**
diff --git a/languages/classes/LanguageEo.php b/languages/classes/LanguageEo.php
deleted file mode 100644 (file)
index 3fec5fc..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-<?php
-/**
- * Esperanto (Esperanto) specific code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author Brion Vibber <brion@pobox.com>
- * @ingroup Language
- */
-
-/**
- * Esperanto (Esperanto)
- *
- * @ingroup Language
- */
-class LanguageEo extends Language {
-       /**
-        * Wrapper for charset conversions.
-        *
-        * In most languages, this calls through to standard system iconv(), but
-        * for Esperanto we're also adding a special pseudo-charset to convert
-        * accented characters to/from the ASCII-friendly "X" surrogate coding:
-        *
-        *     cx = ĉ     cxx = cx
-        *     gx = ĝ     gxx = gx
-        *     hx = ĥ     hxx = hx
-        *     jx = ĵ     jxx = jx
-        *     sx = ŝ     sxx = sx
-        *     ux = ŭ     uxx = ux
-        *     xx = x
-        *
-        *   http://en.wikipedia.org/wiki/Esperanto_orthography#X-system
-        *   http://eo.wikipedia.org/wiki/X-sistemo
-        *
-        * X-conversion is applied, in either direction, between "utf-8" and "x" charsets;
-        * this comes into effect when input is run through $wgRequest->getText() and the
-        * $wgEditEncoding is set to 'x'.
-        *
-        * In the long run, this should be moved out of here and into the client-side
-        * editor behavior; the original server-side translation system dates to 2002-2003
-        * when many browsers with really bad Unicode support were still in use.
-        *
-        * @param string $in Input character set
-        * @param string $out Output character set
-        * @param string $string Text to be converted
-        * @return string
-        */
-       public function iconv( $in, $out, $string ) {
-               if ( strcasecmp( $in, 'x' ) == 0 && strcasecmp( $out, 'utf-8' ) == 0 ) {
-                       return preg_replace_callback(
-                               '/([cghjsu]x?)((?:xx)*)(?!x)/i',
-                               [ $this, 'strrtxuCallback' ], $string );
-               } elseif ( strcasecmp( $in, 'UTF-8' ) == 0 && strcasecmp( $out, 'x' ) == 0 ) {
-                       # Double Xs only if they follow cxapelutaj literoj.
-                       return preg_replace_callback(
-                               '/((?:[cghjsu]|\xc4[\x88\x89\x9c\x9d\xa4\xa5\xb4\xb5]|\xc5[\x9c\x9d\xac\xad])x*)/i',
-                               [ $this, 'strrtuxCallback' ], $string );
-               }
-               return parent::iconv( $in, $out, $string );
-       }
-
-       /**
-        * @param array $matches
-        * @return string
-        */
-       function strrtuxCallback( $matches ) {
-               static $ux = [
-                       'x' => 'xx', 'X' => 'Xx',
-                       "\xc4\x88" => "Cx", "\xc4\x89" => "cx",
-                       "\xc4\x9c" => "Gx", "\xc4\x9d" => "gx",
-                       "\xc4\xa4" => "Hx", "\xc4\xa5" => "hx",
-                       "\xc4\xb4" => "Jx", "\xc4\xb5" => "jx",
-                       "\xc5\x9c" => "Sx", "\xc5\x9d" => "sx",
-                       "\xc5\xac" => "Ux", "\xc5\xad" => "ux",
-               ];
-               return strtr( $matches[1], $ux );
-       }
-
-       /**
-        * @param array $matches
-        * @return string
-        */
-       function strrtxuCallback( $matches ) {
-               static $xu = [
-                       'xx' => 'x', 'xX' => 'x',
-                       'Xx' => 'X', 'XX' => 'X',
-                       "Cx" => "\xc4\x88", "CX" => "\xc4\x88",
-                       "cx" => "\xc4\x89", "cX" => "\xc4\x89",
-                       "Gx" => "\xc4\x9c", "GX" => "\xc4\x9c",
-                       "gx" => "\xc4\x9d", "gX" => "\xc4\x9d",
-                       "Hx" => "\xc4\xa4", "HX" => "\xc4\xa4",
-                       "hx" => "\xc4\xa5", "hX" => "\xc4\xa5",
-                       "Jx" => "\xc4\xb4", "JX" => "\xc4\xb4",
-                       "jx" => "\xc4\xb5", "jX" => "\xc4\xb5",
-                       "Sx" => "\xc5\x9c", "SX" => "\xc5\x9c",
-                       "sx" => "\xc5\x9d", "sX" => "\xc5\x9d",
-                       "Ux" => "\xc5\xac", "UX" => "\xc5\xac",
-                       "ux" => "\xc5\xad", "uX" => "\xc5\xad",
-               ];
-               return strtr( $matches[1], $xu ) . strtr( $matches[2], $xu );
-       }
-
-       function initEncoding() {
-               global $wgEditEncoding;
-               $wgEditEncoding = 'x';
-       }
-}
index 73f57e4..836fb86 100644 (file)
@@ -374,6 +374,7 @@ class Names {
                'shi' => 'Tašlḥiyt/ⵜⴰⵛⵍⵃⵉⵜ', # Tachelhit (multiple scripts - defaults to Latin)
                'shi-tfng' => 'ⵜⴰⵛⵍⵃⵉⵜ', # Tachelhit (Tifinagh script)
                'shi-latn' => 'Tašlḥiyt', # Tachelhit (Latin script)
+               'shn' => 'ၽႃႇသႃႇတႆး ', # Shan
                'si' => 'සිංහල', # Sinhalese
                'simple' => 'Simple English', # Simple English
                'sk' => 'slovenčina', # Slovak
index 87e957d..37a0584 100644 (file)
@@ -421,7 +421,6 @@ public static $zh2Hant = [
 '埘' => '塒',
 '埙' => '塤',
 '埚' => '堝',
-'埯' => '垵',
 '堑' => '塹',
 '堕' => '墮',
 '墙' => '牆',
@@ -3205,7 +3204,7 @@ public static $zh2Hant = [
 '不好干预' => '不好干預',
 '不嫌母丑' => '不嫌母醜',
 '不寒而栗' => '不寒而慄',
-'不吊' => '不弔',
+'不吊,' => '不弔,',
 '不卷' => '不捲',
 '不采' => '不採',
 '不斗胆' => '不斗膽',
@@ -3817,6 +3816,7 @@ public static $zh2Hant = [
 '并入' => '併入',
 '并兼' => '併兼',
 '并到' => '併到',
+'并力' => '併力',
 '并合' => '併合',
 '并名' => '併名',
 '并吞' => '併吞',
@@ -4036,7 +4036,7 @@ public static $zh2Hant = [
 '其次辟地' => '其次辟地',
 '其余' => '其餘',
 '典范' => '典範',
-'兼并' => '兼',
+'兼并' => '兼',
 '冉有仆' => '冉有僕',
 '冗余' => '冗餘',
 '冤仇' => '冤讎',
@@ -4423,6 +4423,7 @@ public static $zh2Hant = [
 '吟游' => '吟遊',
 '吧台' => '吧檯',
 '含齿戴发' => '含齒戴髮',
+'吸干' => '吸乾',
 '吹干' => '吹乾',
 '吹发' => '吹髮',
 '吹胡' => '吹鬍',
@@ -4966,7 +4967,6 @@ public static $zh2Hant = [
 '嶒棱' => '嶒稜',
 '岳岳' => '嶽嶽',
 '岳麓' => '嶽麓',
-'川谷' => '川穀',
 '巡回医疗' => '巡回醫療',
 '巡回' => '巡迴',
 '巡游' => '巡遊',
@@ -5009,7 +5009,6 @@ public static $zh2Hant = [
 '年谷' => '年穀',
 '年里' => '年裡',
 '年鉴' => '年鑑',
-'并力' => '并力',
 '并州' => '并州',
 '并日而食' => '并日而食',
 '并迭' => '并迭',
@@ -5120,7 +5119,6 @@ public static $zh2Hant = [
 '吊孝' => '弔孝',
 '吊客' => '弔客',
 '吊宴' => '弔宴',
-'吊带' => '弔帶',
 '吊影' => '弔影',
 '吊恤' => '弔恤',
 '吊慰' => '弔慰',
@@ -5129,7 +5127,6 @@ public static $zh2Hant = [
 '吊撒' => '弔撒',
 '吊文' => '弔文',
 '吊旗' => '弔旗',
-'吊死' => '弔死',
 '吊民' => '弔民',
 '吊祭' => '弔祭',
 '吊纸' => '弔紙',
@@ -5581,6 +5578,7 @@ public static $zh2Hant = [
 '抱素怀朴' => '抱素懷樸',
 '抵御' => '抵禦',
 '抹干' => '抹乾',
+'抽干' => '抽乾',
 '抽公签' => '抽公籤',
 '抽签' => '抽籤',
 '抿发' => '抿髮',
@@ -5698,6 +5696,8 @@ public static $zh2Hant = [
 '扫荡' => '掃蕩',
 '授勋' => '授勳',
 '掌柜' => '掌柜',
+'排干' => '排乾',
+'排干部' => '排幹部',
 '排骨面' => '排骨麵',
 '挂名' => '掛名',
 '挂历' => '掛曆',
@@ -7622,6 +7622,7 @@ public static $zh2Hant = [
 '药面儿' => '藥麵兒',
 '苏崑' => '蘇崑',
 '苏昆' => '蘇崑',
+'苹婆' => '蘋婆',
 '苹果' => '蘋果',
 '苹果干' => '蘋果乾',
 '兰溪市' => '蘭谿市',
@@ -8514,6 +8515,7 @@ public static $zh2Hant = [
 '炼金术' => '鍊金術',
 '锲而不舍' => '鍥而不捨',
 '镰仓' => '鎌倉',
+'镇里' => '鎮裡',
 '镜图里' => '鏡圖裡',
 '锈病' => '鏽病',
 '锈菌' => '鏽菌',
@@ -9428,7 +9430,6 @@ public static $zh2Hant = [
 '龜山庄' => '龜山庄',
 '龟鉴' => '龜鑑',
 ',并力' => ',並力',
-',并力攻' => ',并力攻',
 ',并力討' => ',并力討',
 ',并力讨' => ',并力討',
 ',个中' => ',箇中',
@@ -9863,9 +9864,7 @@ public static $zh2Hans = [
 '圞' => '𪢮',
 '坿' => '附',
 '垜' => '垛',
-'垵' => '埯',
 '埡' => '垭',
-'埰' => '采',
 '執' => '执',
 '堅' => '坚',
 '堊' => '垩',
@@ -13769,6 +13768,7 @@ public static $zh2Hans = [
 '甦醒' => '苏醒',
 '苧烯' => '苧烯',
 '薴烯' => '苧烯',
+'蘋婆' => '苹婆',
 '蘋果' => '苹果',
 '荠苧' => '荠苧',
 '榮陞' => '荣升',
@@ -14088,7 +14088,6 @@ public static $zh2TW = [
 '威士顿康星' => '威斯康辛',
 '威尔士' => '威爾斯',
 '威爾士' => '威爾斯',
-'字库' => '字型檔',
 '存盘' => '存檔',
 '孟德爾遜' => '孟德爾頌',
 '门德尔松' => '孟德爾頌',
@@ -17057,7 +17056,10 @@ public static $zh2HK = [
 '見著述' => '見著述',
 '見著錄' => '見著錄',
 '視著' => '視着',
+'視著作' => '視著作',
 '視著名' => '視著名',
+'視著稱' => '視著稱',
+'視著者' => '視著者',
 '角落里' => '角落裏',
 '分辨率' => '解像度',
 '解析度' => '解像度',
@@ -17389,6 +17391,7 @@ public static $zh2HK = [
 '鋪著者' => '鋪著者',
 '鋪著述' => '鋪著述',
 '鋪著錄' => '鋪著錄',
+'镇里' => '鎮裏',
 '镜图里' => '鏡圖裏',
 '钟在寺里' => '鐘在寺裏',
 '狄托' => '鐵托',
@@ -18394,7 +18397,6 @@ public static $zh2CN = [
 '威爾斯' => '威尔士',
 '威斯伐倫' => '威斯特法伦',
 '字型大小' => '字号',
-'字型檔' => '字库',
 '欄位' => '字段',
 '位元組' => '字节',
 '存在著' => '存在着',
@@ -19852,7 +19854,10 @@ public static $zh2CN = [
 '見著述' => '见著述',
 '規畫' => '规划',
 '視著' => '视着',
+'視著作' => '视著作',
 '視著名' => '视著名',
+'視著稱' => '视著称',
+'視著者' => '视著者',
 '占士邦' => '詹姆斯·邦德',
 '警戒著' => '警戒着',
 '計畫' => '计划',
index f63f7c3..97a8233 100644 (file)
@@ -10,7 +10,8 @@
                        "GeekEmad",
                        "Nemo bis",
                        "Shbib Al-Subaie",
-                       "Macofe"
+                       "Macofe",
+                       "علاء"
                ]
        },
        "tog-usenewrc": ")جمّع التعديلات حسب الصفحة في أحدث التغييرات وقائمة المراقبة (يتطلب جافاسكربت",
        "rc-enhanced-hide": "أخفِ التفاصيل",
        "recentchangeslinked": "تغييرات ذات علاقة",
        "recentchangeslinked-title": "التغييرات المرتبطة ب \"$1\"",
-       "recentchangeslinked-summary": "هذه قائمة بالتغييرات التي تمت حديثا للصفحات الموصولة من صفحة معينة (أو إلى الأعضاء ضمن تصنيف معين).\nالصفحات في [[Special:Watchlist|قائمة مراقبتك]] '''عريضة'''",
+       "recentchangeslinked-summary": "هذه قائمة بالتغييرات التي تمت حديثاً للصفحات الموصولة من صفحة معينة (أو إلى الأعضاء ضمن تصنيف معين).\nالصفحات في [[Special:Watchlist|قائمة مراقبتك]] '''عريضة'''",
        "recentchangeslinked-page": "اسم الصفحة:",
-       "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضا عن ذلك",
+       "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضاً عن ذلك",
        "uploadlogpage": "سجل الرفع",
        "filedesc": "ملخص:",
        "license": "ترخيص:",
index fa0ab1c..7bdc097 100644 (file)
        "mw-widgets-dateinput-placeholder-month": "JJJJ-MM",
        "mw-widgets-titleinput-description-new-page": "bladsy bestaan nog nie",
        "mw-widgets-titleinput-description-redirect": "aanstuur na $1",
-       "api-error-blacklisted": "Kies asseblief 'n ander, beskrywende titel.",
        "log-action-filter-all": "Alle",
        "authprovider-resetpass-skip-label": "Slaan oor"
 }
index ee3d06e..738cd5e 100644 (file)
@@ -61,7 +61,9 @@
                        "Maroen1990",
                        "Sonic N800",
                        "Jdforrester",
-                       "Alaa"
+                       "Alaa",
+                       "Izoozo",
+                       "علاء"
                ]
        },
        "tog-underline": "سطر تحت الوصلات:",
@@ -90,7 +92,7 @@
        "tog-enotifrevealaddr": "أظهر عنوان بريدي الإلكتروني في إشعارات البريد الإلكتروني",
        "tog-shownumberswatching": "اعرض عدد المستخدمين المراقبين",
        "tog-oldsig": "التوقيع الحالي:",
-       "tog-fancysig": "وضع الوصلة يدويا واستعمال نص الويكي",
+       "tog-fancysig": "وضع الوصلة يدوياً واستعمال نص الويكي",
        "tog-uselivepreview": "استعمال المعاينة المباشرة",
        "tog-forceeditsummary": "نبهني عند عدم إدخال ملخص تعديل",
        "tog-watchlisthideown": "أخف تعديلاتي من قائمة المراقبة",
        "category_header": "صفحات تصنيف «$1»",
        "subcategories": "تصنيفات فرعية",
        "category-media-header": "ملفات تصنيف \"$1\"",
-       "category-empty": "هذا التصنيف لا يحتوي حاليا على صفحات أو ملفات.",
+       "category-empty": "هذا التصنيف لا يحتوي حالياً على أي صفحات أو ملفات.",
        "hidden-categories": "{{PLURAL:$1|لا تصنيفات مخفية|تصنيف مخفي|تصنيفان مخفيان|تصنيفات مخفية}}",
        "hidden-category-category": "تصنيفات مخفية",
        "category-subcat-count": "{{PLURAL:$2|هذا التصنيف يحوي التصنيف الفرعي التالي|هذا التصنيف يحوي {{PLURAL:$1||التصنيف الفرعي|تصنيفين فرعيين|$1 تصنيفات فرعية}}، من إجمالي $2.}}",
        "badsig": "توقيع خام غير صحيح؛ تحقق من وسوم HTML.",
        "badsiglength": "توقيعك طويل جدا.\nيجب أن يكون أقل من $1 {{PLURAL:$1|حرف|حروف}}.",
        "yourgender": "كيف تفضل أن توصف؟",
-       "gender-unknown": "عند ذكرك، البرنامج سيستخدم كلمات محايدة النوع متى ما كان ذلك ممكنا",
+       "gender-unknown": "عند ذكرك، البرنامج سيستخدم كلمات محايدة النوع متى ما كان ذلك ممكناً",
        "gender-male": "هو يعدل صفحات الويكي",
        "gender-female": "هي تعدل صفحات الويكي",
-       "prefs-help-gender": "ضبط هذا التفضيل اختياري.\nيستخدم البرنامج هذه القيمة لمخاطبتك ومخاطبة الآخرين عنك وفقا للصيغة النحوية الملائمة للجنس.\nستكون هذه المعلومة علنية.",
+       "prefs-help-gender": "ضبط هذا التفضيل اختياري.\nيستخدم البرنامج هذه القيمة لمخاطبتك ومخاطبة الآخرين عنك وفقاً للصيغة النحوية الملائمة للجنس.\nهذه المعلومة ستكون علنية.",
        "email": "البريد الإلكتروني",
        "prefs-help-realname": "الاسم الحقيقي اختياري.\nلو اخترت أن توفره، فسيستخدم في الإشارة إلى عملك.",
        "prefs-help-email": "تحديد عنوان البريد الإلكتروني اختياري، ولكنه يلزم لإعادة تعيين كلمة المرور في حال نسيت كلمة المرور الخاصة بك.",
        "userrights-removed-self": "أزلت بنجاح صلاحياتك، ولن تتمكن من الوصول لهذه الصفحة مجددا.",
        "group": "المجموعة:",
        "group-user": "مستخدمون",
-       "group-autoconfirmed": "مستخدمون مؤكدون تلقائيا",
+       "group-autoconfirmed": "مستخدمون مؤكدون تلقائياً",
        "group-bot": "بوتات",
        "group-sysop": "مديرو نظام",
        "group-bureaucrat": "بيروقراطيون",
        "group-bureaucrat-member": "{{GENDER:$1|بيروقراط}}",
        "group-suppress-member": "{{GENDER:$1|ناظر|ناظرة}}",
        "grouppage-user": "{{ns:project}}:مستخدمون",
-       "grouppage-autoconfirmed": "{{ns:project}}:مستخدمون مؤكدون تلقائيا",
+       "grouppage-autoconfirmed": "{{ns:project}}:مستخدمون مؤكدون تلقائياً",
        "grouppage-bot": "{{ns:project}}:بوتات",
        "grouppage-sysop": "{{ns:project}}:إداريون",
        "grouppage-bureaucrat": "{{ns:project}}:بيروقراطيون",
        "recentchangeslinked-feed": "تغييرات ذات علاقة",
        "recentchangeslinked-toolbox": "تغييرات ذات علاقة",
        "recentchangeslinked-title": "التغييرات المرتبطة بصفحة «$1»",
-       "recentchangeslinked-summary": "هذه قائمة بالتغييرات التي تمت حديثا للصفحات الموصولة من صفحة معينة (أو إلى الأعضاء ضمن تصنيف معين).\nالصفحات في [[Special:Watchlist|قائمة مراقبتك]] '''مغلظة'''",
+       "recentchangeslinked-summary": "هذه قائمة بالتغييرات التي تمت حديثاً للصفحات الموصولة من صفحة معينة (أو إلى الأعضاء ضمن تصنيف معين).\nالصفحات في [[Special:Watchlist|قائمة مراقبتك]] '''عريضة'''",
        "recentchangeslinked-page": "اسم الصفحة:",
-       "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضا عن ذلك",
+       "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضاً عن ذلك",
        "recentchanges-page-added-to-category": "[[:$1]] أضيفت إلى التصنيف",
        "recentchanges-page-added-to-category-bundled": "أضيفت [[:$1]] و{{PLURAL:$2|صفحة واحدة|صفحتان|$2 صفحات}} إلى التصنيف",
        "recentchanges-page-removed-from-category": "أزيلت [[:$1]] من التصنيف",
        "watching": "يراقب...",
        "unwatching": "إزالة المراقبة...",
        "watcherrortext": "حدث خطأ أثناء تغيير إعدادات الرصد الخاصة بك \"$1\".",
-       "enotif_reset": "علم على كل الصفحات كمَزُورة",
+       "enotif_reset": "علم على كل الصفحات كمرئية",
        "enotif_impersonal_salutation": "مستخدم {{SITENAME}}",
        "enotif_subject_deleted": "الصفحة {{SITENAME}} $1 حذفها {{الجنس: $2 | $2 }}",
        "enotif_subject_created": "الصفحة {{SITENAME}}  $1  أنشأها {{الجنس: $2 | $2 }}",
        "mw-widgets-dateinput-no-date": "لا تاريخ تم اختياره",
        "mw-widgets-titleinput-description-new-page": "الصفحة غير موجودة بعد",
        "mw-widgets-titleinput-description-redirect": "تحويل إلى $1",
-       "api-error-blacklisted": "اختر عنوانا مختلفا ومفهوما.",
        "sessionmanager-tie": "لا يمكن جمع أنواع استيثاق متعددة: $1.",
        "sessionprovider-generic": "جلسات $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "جلسات قائمة على ملفات تعريف الارتباط (كوكيز)",
index fb709a3..e283439 100644 (file)
@@ -12,7 +12,8 @@
                        "아라",
                        "Fitoschido",
                        "Macofe",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Tokvo"
                ]
        },
        "tog-underline": "Sorrayar enllaces:",
        "rightslogtext": "Esti ye un rexistru de los cambeos nos permisos d'usuariu.",
        "action-read": "lleer esta páxina",
        "action-edit": "editar esta páxina",
-       "action-createpage": "crear páxines",
-       "action-createtalk": "crear páxines d'alderique",
+       "action-createpage": "crear esta páxina",
+       "action-createtalk": "crear esta páxina d'alderique",
        "action-createaccount": "crear esta cuenta d'usuariu",
        "action-autocreateaccount": "crear automáticamente esta cuenta d'usuariu esterna",
        "action-history": "ver l'historial d'esta páxina",
        "table_pager_limit_label": "Elementos por páxina:",
        "table_pager_limit_submit": "Dir",
        "table_pager_empty": "Nun hai resultaos",
-       "autosumm-blank": "Desaniciáu el conteníu de la páxina",
+       "autosumm-blank": "Desaniciáu'l conteníu de la páxina",
        "autosumm-replace": "Sustituyendo la páxina por '$1'",
        "autoredircomment": "Redirixendo a [[$1]]",
        "autosumm-new": "Páxina creada con «$1»",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "la páxina inda nun esiste",
        "mw-widgets-titleinput-description-redirect": "redirixir a $1",
-       "api-error-blacklisted": "Escueyi un títulu distintu, más descriptivu.",
        "sessionmanager-tie": "Nun puen combinase dellos tipos de solicitú d'identificación: $1.",
        "sessionprovider-generic": "sesiones $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sesiones basaes en cookies",
        "log-action-filter-newusers": "Tipu de creación de cuenta:",
        "log-action-filter-patrol": "Tipu de patrulla:",
        "log-action-filter-protect": "Tipu de proteición:",
-       "log-action-filter-rights": "Tipu de cambéu de permisos",
-       "log-action-filter-suppress": "Tipu de supresión",
+       "log-action-filter-rights": "Tipu de cambéu de permisos:",
+       "log-action-filter-suppress": "Tipu de supresión:",
        "log-action-filter-upload": "Tipu de carga:",
        "log-action-filter-all": "Too",
        "log-action-filter-block-block": "Bloquéu",
        "authmanager-provider-temporarypassword": "Contraseña temporal",
        "authprovider-resetpass-skip-label": "Saltar",
        "authprovider-resetpass-skip-help": "Saltar el reaniciu de la contraseña.",
+       "specialpage-securitylevel-not-allowed-title": "Nun ta permitío",
+       "cannotauth-not-allowed-title": "Permisu refugáu",
+       "cannotauth-not-allowed": "Nun tienes permisu pa usar esta páxina",
        "credentialsform-account": "Nome de la cuenta:",
        "cannotlink-no-provider-title": "Nun hai cuentes enllazables",
        "cannotlink-no-provider": "Nun hai cuentes enllazables.",
index 0979cdb..58955dc 100644 (file)
        "site-atom-feed": "$1 آتوم فید",
        "page-rss-feed": "«$1» آراِس‌اِس فید",
        "page-atom-feed": "«$1» آتوم فید",
-       "red-link-title": "$1 (صفحه یوْخدور)",
+       "red-link-title": "$1 (صفحه یوْخدور)",
        "sort-descending": "آزالان سیرالاماق",
        "sort-ascending": "چوْخالان سیرالاماق",
        "nstab-main": "صفحه",
        "number_of_watching_users_pageview": "[{{PLURAL:$1|بیر|$1}} ایزله‌ین ایستیفاده‌چی]",
        "rc_categories": "بؤلمه‌لره محدودلاشدیر («|» ایله آییر)",
        "rc_categories_any": "سئچیلمیشلرین هر بیریسی",
-       "rc-change-size-new": "دَییشیکلیک‌دن سونرا {{PLURAL:|بیر|$1}} بایت",
+       "rc-change-size-new": "دÙ\8eÛ\8cÛ\8cØ´Û\8cÚ©Ù\84Û\8cÚ©â\80\8cدÙ\86 Ø³Ù\88Ù\92Ù\86را {{PLURAL:|بÛ\8cر|$1}} Ø¨Ø§Û\8cت",
        "newsectionsummary": "/* $1 */ یئنی بؤلمه",
        "rc-enhanced-expand": "تفصیل‌لری گؤستر",
        "rc-enhanced-hide": "تفصیل‌لری گیزلت",
index 4eb7d3d..d6cfcca 100644 (file)
        "botpasswords-label-update": "Абнавіць",
        "botpasswords-label-cancel": "Скасаваць",
        "botpasswords-label-delete": "Выдаліць",
-       "botpasswords-label-resetpassword": "Ð\90Ñ\87Ñ\8bÑ\81Ñ\8cÑ\86Ñ\96ць пароль",
+       "botpasswords-label-resetpassword": "СкÑ\96нÑ\83ць пароль",
        "botpasswords-label-grants": "Прыдатныя дазволы:",
        "botpasswords-help-grants": "Кожны дазвол дае доступ да правоў удзельніка, якія ўжо мае рахунак удзельніка. Глядзіце [[Special:ListGrants|табліцу дазволаў]] дзеля дадатковых зьвестак.",
        "botpasswords-label-restrictions": "Абмежаваньні на выкарыстаньне:",
        "content-model-css": "CSS",
        "content-json-empty-object": "Пусты аб’ект",
        "content-json-empty-array": "Пусты масіў",
+       "deprecated-self-close-category": "Старонкі зь няслушнымі самазакрытымі HTML-тэгамі",
+       "deprecated-self-close-category-desc": "Старонка ўтрымлівае няслушныя самазакрытыя HTML-тэгі, такія як <code>&lt;b/></code> ці <code>&lt;span/></code>. Іх паводзіны ў хуткім часе будуць зьмененыя ў адпаведнасьці з спэцыфікацыяй HTML5, таму іх ўжываньне ў вікітэксьце лічыцца састарэлым.",
        "duplicate-args-warning": "<strong>Папярэджаньне:</strong> [[:$1]] выклікае [[:$2]] з больш чым адным значэньнем парамэтру «$3». Толькі апошняе з пададзеных значэньняў будзе ўжытае.",
        "duplicate-args-category": "Старонкі, на якіх у шаблёнах выкарыстоўваюцца парамэтры-дублікаты",
        "duplicate-args-category-desc": "Старонкі, якія ўтрымліваюць шаблёны з парамэтрамі-дублікатамі, напрыклад, <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> або <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "revertpage": "Рэдагаваньні [[Special:Contributions/$2|$2]] ([[User talk:$2|гутаркі]]) скасаваныя да папярэдняй вэрсіі [[User:$1|$1]]",
        "revertpage-nouser": "Рэдагаваньні схаванага ўдзельніка скасаваныя да папярэдняй вэрсіі {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Адмененыя рэдагаваньні $1;\nвернутая папярэдняя вэрсія $2.",
+       "rollback-success-notify": "Адмененыя праўкі $1;\nвернутая папярэдняя вэрсія $2. [$3 Паказаць зьмены]",
        "sessionfailure-title": "Памылка сэсіі",
        "sessionfailure": "Магчыма ўзьніклі праблемы ў Вашым цяперашнім сэансе працы;\nгэта дзеяньне было скасавана для прадухіленьня перахопу сэансу.\nКалі ласка, націсьніце «назад» і перазагрузіце старонку, зь якой Вы прыйшлі, і паспрабуйце ізноў.",
        "changecontentmodel": "Зьмена мадэлі зьместу старонкі",
        "changecontentmodel-success-text": "Тып зьместу [[:$1]] быў зьменены.",
        "changecontentmodel-cannot-convert": "Зьмест [[:$1]] ня можа быць ператвораны ў тып $2.",
        "changecontentmodel-nodirectediting": "Мадэль зьместу $1 не падтрымлівае наўпроставае рэдагаваньне",
+       "changecontentmodel-emptymodels-title": "Няма даступных мадэляў зьместу",
+       "changecontentmodel-emptymodels-text": "Зьмест на [[:$1]] ня можа быць ператвораны ні ў які тып.",
        "log-name-contentmodel": "Журнал зьменаў мадэляў зьместу",
        "log-description-contentmodel": "Падзеі, зьвязаныя з мадэлямі зьместу старонак",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|стварыў|стварыла}} старонку $3 з дапамогай нестандартнай мадэлі зьместу «$5»",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|зьмяніў|зьмяніла}} мадэль зьместу старонкі $3 з «$4» на «$5»",
        "logentry-contentmodel-change-revertlink": "адкаціць",
        "logentry-contentmodel-change-revert": "адкат",
        "sp-contributions-username": "IP-адрас альбо імя ўдзельніка/ўдзельніцы:",
        "sp-contributions-toponly": "Паказваць толькі зьмены, якія зьяўляюцца апошнімі вэрсіямі",
        "sp-contributions-newonly": "Паказваць толькі праўкі, якімі былі створаныя старонкі",
+       "sp-contributions-hideminor": "Схаваць дробныя праўкі",
        "sp-contributions-submit": "Шукаць",
        "whatlinkshere": "Спасылкі на старонку",
        "whatlinkshere-title": "Старонкі, якія спасылаюцца на $1",
        "ipb-unblock": "Разблякаваць рахунак ўдзельніка ці IP-адрас",
        "ipb-blocklist": "Паказаць існуючыя блякаваньні",
        "ipb-blocklist-contribs": "Унёсак $1",
+       "ipb-blocklist-duration-left": "засталося $1",
        "unblockip": "Разблякаваць удзельніка",
        "unblockiptext": "Карыстайцеся пададзенай ніжэй формай для аднаўленьня магчымасьці рэдагаваньня для раней заблякаванага IP-адрасу альбо рахунку ўдзельніка.",
        "ipusubmit": "Зьняць гэта блякаваньне",
        "block-log-flags-hiddenname": "імя ўдзельніка схаванае",
        "range_block_disabled": "Адміністратарам забаронена блякаваць дыяпазоны.",
        "ipb_expiry_invalid": "Няслушны тэрмін блякаваньня.",
+       "ipb_expiry_old": "Час сканчэньня ўжо мінуў.",
        "ipb_expiry_temp": "Блякаваньні са схаваньнем імя ўдзельніка павінны быць бестэрміновымі.",
        "ipb_hide_invalid": "Немагчыма схаваць гэты рахунак; зь яго зроблена больш чым {{PLURAL:$1|$1 рэдагаваньне|$1 рэдагаваньні|$1 рэдагаваньняў}}.",
        "ipb_already_blocked": "«$1» ужо заблякаваны",
        "lockdbsuccesstext": "База зьвестак была заблякаваная.<br />\nНе забудзьцеся [[Special:UnlockDB|зьняць блякаваньне]] пасьля сканчэньня абслугоўваньня.",
        "unlockdbsuccesstext": "База зьвестак была разблякаваная.",
        "lockfilenotwritable": "Немагчыма запісаць у файл блякаваньняў базы зьвестак.\nБлякаваньне ці разблякаваньне базы зьвестак патрабуе, каб вэб-сэрвэр меў дазвол на запіс у гэты файл.",
+       "databaselocked": "База зьвестак ужо заблякаваная.",
        "databasenotlocked": "База зьвестак не заблякаваная.",
        "lockedbyandtime": "($1 $2 у $3)",
        "move-page": "Перанесьці $1",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
        "mw-widgets-titleinput-description-new-page": "старонка яшчэ не існуе",
        "mw-widgets-titleinput-description-redirect": "перанакіраваньне на $1",
-       "api-error-blacklisted": "Калі ласка, выбярыце іншую, апісальную назву.",
-       "randomrootpage": "Выпадковая карэнная старонка"
+       "randomrootpage": "Выпадковая карэнная старонка",
+       "changecredentials": "Зьмена ўліковых зьвестак",
+       "removecredentials": "Выдаленьне ўліковых зьвестак",
+       "removecredentials-submit": "Выдаліць уліковыя зьвесткі",
+       "credentialsform-provider": "Тып уліковых зьвестак:",
+       "credentialsform-account": "Назва рахунку:"
 }
index dc49adf..0b8d5f8 100644 (file)
@@ -34,7 +34,8 @@
                        "Xð",
                        "Miroslav35232",
                        "Ket",
-                       "Ricordo.tenerissimo"
+                       "Ricordo.tenerissimo",
+                       "Plamen"
                ]
        },
        "tog-underline": "Подчертаване на препратките:",
        "whatlinkshere-prev": "{{PLURAL:$1|предишна|предишни $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|следваща|следващи $1}}",
        "whatlinkshere-links": "← препратки",
-       "whatlinkshere-hideredirs": "$1 Ð½Ð° Ð¿Ñ\80енаÑ\81оÑ\87ваÑ\89и Ñ\81Ñ\82Ñ\80аниÑ\86и",
-       "whatlinkshere-hidetrans": "$1 Ð½Ð° Ð²ÐºÐ»Ñ\8eÑ\87ени Ñ\81Ñ\82Ñ\80аниÑ\86и",
-       "whatlinkshere-hidelinks": "$1 Ð½Ð° Ð¿Ñ\80епÑ\80аÑ\82ки",
+       "whatlinkshere-hideredirs": "$1 Ð¿Ñ\80енаÑ\81оÑ\87ваниÑ\8f",
+       "whatlinkshere-hidetrans": "$1 Ð²ÐºÐ»Ñ\8eÑ\87ваниÑ\8f",
+       "whatlinkshere-hidelinks": "$1 препратки",
        "whatlinkshere-hideimages": "$1 на препратки към файла",
        "whatlinkshere-filters": "Филтри",
        "whatlinkshere-submit": "Отваряне",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
        "mw-widgets-titleinput-description-new-page": "страницата все още не съществува",
        "mw-widgets-titleinput-description-redirect": "пренасочване към $1",
-       "api-error-blacklisted": "Моля, изберете различно, описателно заглавие.",
        "randomrootpage": "Случайна начална страница",
        "log-action-filter-protect": "Тип защита:",
        "log-action-filter-upload": "Тип качване:",
index 4d7614f..1626101 100644 (file)
        "passwordreset-nocaller": "একটি আহ্বানকারী প্রদান করা আবশ্যক",
        "passwordreset-nosuchcaller": "আহ্বানকারীর অস্তিত্ব নেই: $1",
        "passwordreset-invalideamil": "ভুল ইমেইল ঠিকানা",
+       "passwordreset-nodata": "একটি ব্যবহারকারীর নাম বা একটি ইমেল ঠিকানা দুটির একটিও সরবরা দেয়া হয়নি",
        "changeemail": "ই-মেইল ঠিকানা পরিবর্তন বা বাতিল",
        "changeemail-header": "আপনার ইমেল ঠিকানা পরিবর্তন করতে এই ফরমটি পূরণ করুন। আপনি যদি আপনার একাউন্ট থেকে যে কোন ইমেল ঠিকানার এসোসিয়েশন অপসারণ করতে চান, তাহলে ফরমটি জমা দেওয়ার সময় নতুন ইমেইল ঠিকানা খালি রাখুন।",
        "changeemail-passwordrequired": "এই পরিবর্তন নিশ্চিত করতে আপনাকে আপনার পাসওয়ার্ড লিখতে হবে।",
        "content-model-css": "সিএসএস",
        "content-json-empty-object": "খালি বস্তু",
        "content-json-empty-array": "খালি অ্যারে",
+       "deprecated-self-close-category": "অবৈধ স্ব-বন্ধকৃত এইচটিএমএল ট্যাগ ব্যবহার করা পাতা",
+       "deprecated-self-close-category-desc": "এই পাতাটি অবৈধ স্ব-বন্ধকৃত এইচটিএমএল ট্যাগ ধারন করে, যেমন <code>&lt;b/></code> বা <code>&lt;span/></code>। এইচটিএমএল৫-এর নির্দিষ্টকরণের সঙ্গে সামঞ্জস্যপূর্ণ হতে এইসবের আচরণ শীঘ্রই পরিবর্তন করা হবে, তাই উইকিপাঠ্যে তাদের ব্যবহার অবচিত হয়েছে।",
        "duplicate-args-warning": "<strong>সতর্কীকরণ:</strong> \"$3\" প্যারামিটারের জন্য একের অধিক মানসহ [[:$1]] [[:$2]] কে আহ্বান করছে। শুধুমাত্র প্রদত্ত শেষ মান ব্যবহৃত হবে।",
        "duplicate-args-category": "টেমপ্লেট আহ্বানে সদৃশ আর্গুমেন্ট ব্যবহার করা পাতা",
        "duplicate-args-category-desc": "এই পাতায় টেমপ্লেট আহ্বান উপস্থিত রয়েছে যা সদৃশ আর্গুমেন্ট ব্যবহার করেছে, যেমন <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> বা <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>।",
        "right-managechangetags": "[[Special:Tags|ট্যাগ]] তৈরি ও সক্রিয়/নিষ্ক্রিয় করুন",
        "right-applychangetags": "সম্পাদনার সাথে [[Special:Tags|ট্যাগ]] যুক্ত করুন",
        "right-changetags": "নির্দিষ্ট সংস্করণ এবং দীর্ঘ সম্পাদনাগুলোতে [[Special:Tags|ট্যাগ]] সংযোজন ও অপসারণ করুন",
+       "right-deletechangetags": "ডাটাবেজ থেকে [[Special:Tags|ট্যাগ]] অপসারণ করা",
        "grant-group-email": "ইমেইল পাঠান",
+       "grant-group-other": "বিবিধ কার্যকলাপ",
        "grant-createaccount": "অ্যাকাউন্ট তৈরি করুন",
        "grant-createeditmovepage": "পাতা তৈরি, সম্পাদনা এবং স্থানান্তর করুন",
        "grant-editmycssjs": "আপনার সিএসএস/জাভাস্ক্রিপ্ট সম্পাদনা করুন",
        "upload-too-many-redirects": "এই ইউআরএলটিতে অনেক বেশি পুনর্নির্দেশনা রয়েছে",
        "upload-http-error": "একটি এইচটিটিপি ত্রুটি দেখা দিয়েছে: $1",
        "upload-copy-upload-invalid-domain": "এই ডোমেইন থেকে আপলোড সম্ভব নয়।",
+       "upload-dialog-disabled": "এই ডায়ালগ ব্যবহার করে ফাইল আপলোড করা এই উইকিতে নিষ্ক্রিয় করা হয়েছে।",
        "upload-dialog-title": "ফাইল আপলোড করুন",
        "upload-dialog-button-cancel": "বাতিল",
        "upload-dialog-button-done": "সম্পন্ন",
        "upload-dialog-button-upload": "আপলোড",
        "upload-form-label-infoform-title": "বিস্তারিত",
        "upload-form-label-infoform-name": "নাম",
+       "upload-form-label-infoform-name-tooltip": "ফাইলের জন্য একটি অদ্বিতীয় বিবরণমূলক শিরোনাম, যেটি ফাইলের নাম হিসাবে পরিবেশন হবে। আপনি ফাঁকা স্থান সহ সমতল ভাষা ব্যবহার করতে পারেন। ফাইল এক্সটেনশন অন্তর্ভুক্ত করবেন না।",
        "upload-form-label-infoform-description": "বিবরণ",
+       "upload-form-label-infoform-description-tooltip": "সংক্ষেপে কাজটি সম্পর্কে উল্লেখযোগ্য সবকিছু বর্ণনা করুন।\nএকটি ছবির জন্য, এতে থাকা প্রধান বিষয়, অনুষ্ঠান, বা জায়গা উল্লেখ করুন।",
        "upload-form-label-usage-title": "ব্যবহার",
        "upload-form-label-usage-filename": "ফাইলের নাম",
        "upload-form-label-own-work": "এটি আমার নিজের কাজ",
        "apihelp": "এপিআই সাহায্য",
        "apihelp-no-such-module": "মডিউল \"$1\" পাওয়া যায়নি।",
        "apisandbox": "এপিআই খেলাঘর",
+       "apisandbox-jsonly": "API খেলাঘর ব্যবহার করতে জাভাস্ক্রিপ্ট প্রয়োজন।",
        "apisandbox-api-disabled": "এপিআই এই সাইটে নিষ্ক্রিয় করা আছে।",
        "apisandbox-fullscreen": "প্যানেল সম্প্রসারণ করুন",
+       "apisandbox-fullscreen-tooltip": "ব্রাউজারের উইন্ডো পূরণ করতে খেলাঘরের প্যানেল প্রসারিত করুন।",
        "apisandbox-unfullscreen": "পাতা দেখাও",
        "apisandbox-submit": "অনুরোধ রাখুন",
        "apisandbox-reset": "পরিস্কার",
        "mw-widgets-dateinput-placeholder-month": "বববব-মম",
        "mw-widgets-titleinput-description-new-page": "পাতা এখনো বিদ্যমান নয়",
        "mw-widgets-titleinput-description-redirect": "$1-এ পুনঃনির্দেশিত",
-       "api-error-blacklisted": "অনুগ্রহ করে অপর কোনো বর্ণনামূলক নাম ব্যবহার করুন।",
        "sessionmanager-tie": "একাধিক অনুরোধের প্রমাণীকরণের ধরন একত্রিত করা যাবে না: $1।",
        "sessionprovider-generic": "$1টি সেশন",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "কুকি-ভিত্তিক সেশন",
        "log-action-filter-delete-restore": "পাতা পুনঃরুদ্ধার",
        "log-action-filter-delete-event": "লগ অপসারণ",
        "log-action-filter-delete-revision": "সংশোধন অপসারণ",
+       "log-action-filter-import-interwiki": "আন্তঃউইকি আমদানি",
+       "log-action-filter-import-upload": "XML আপলোড কর্তৃক আমদানি",
+       "log-action-filter-newusers-create": "বেনামী ব্যবহারকারী দ্বারা সৃষ্টি",
+       "log-action-filter-newusers-create2": "নিবন্ধিত ব্যবহারকারী দ্বারা সৃষ্টি",
+       "log-action-filter-newusers-autocreate": "স্বয়ংক্রিয় সৃষ্টি",
+       "log-action-filter-newusers-byemail": "ই-মেইলে পাসওয়ার্ড প্রেরণের দ্বারা সৃষ্টি",
        "log-action-filter-patrol-patrol": "ম্যানুয়াল টহল",
        "log-action-filter-patrol-autopatrol": "স্বয়ংক্রিয় টহল",
        "log-action-filter-protect-protect": "সুরক্ষা",
        "log-action-filter-protect-modify": "সুরক্ষা পরিমার্জন",
        "log-action-filter-protect-unprotect": "অসুরক্ষা",
+       "log-action-filter-protect-move_prot": "সুরক্ষা স্থানান্তরিত",
+       "log-action-filter-rights-rights": "ম্যানুয়াল পরিবর্তন",
        "log-action-filter-rights-autopromote": "স্বয়ংক্রিয় পরিবর্তন",
        "log-action-filter-upload-upload": "নতুন আপলোড",
        "log-action-filter-upload-overwrite": "পুনঃআপলোড",
+       "authmanager-authplugin-setpass-failed-title": "পাসওয়ার্ড পরিবর্তন ব্যর্থ হয়েছে",
        "authmanager-authplugin-setpass-bad-domain": "অবৈধ ডোমেইন।",
        "authmanager-autocreate-noperm": "স্বয়ংক্রিয় অ্যাকাউন্ট সৃষ্টি মঞ্জুরিপ্রাপ্ত নয়।",
        "authmanager-userdoesnotexist": "ব্যবহারকারী অ্যাকাউন্ট \"$1\" অনিবন্ধিত।",
        "authmanager-realname-label": "প্রকৃত নাম",
        "authmanager-realname-help": "ব্যবহারকারীর প্রকৃত নাম",
        "authmanager-provider-temporarypassword": "অস্থায়ী পাসওয়ার্ড",
+       "authprovider-confirmlink-success-line": "$1: সংযোগ করা সফল হয়েছে।",
        "authprovider-resetpass-skip-label": "উপেক্ষা করো",
        "authprovider-resetpass-skip-help": "পাসওয়ার্ড পুনঃস্থাপন করা উপেক্ষা করুন।",
        "authform-wrongtoken": "ভুল টোকেন",
index 5a5388e..cdf6cb1 100644 (file)
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "simboli",
        "special-characters-group-greek": "grčki",
+       "special-characters-group-greekextended": "prošireni grčki",
        "special-characters-group-cyrillic": "ćirilica",
        "special-characters-group-arabic": "arapski",
        "special-characters-group-arabicextended": "prošireni arapski",
        "mw-widgets-dateinput-no-date": "Nikakav datum nije izabran",
        "mw-widgets-titleinput-description-new-page": "stranica još ne postoji",
        "mw-widgets-titleinput-description-redirect": "preusmjerava na $1",
-       "api-error-blacklisted": "Molimo izaberite drugačiji, deskriptivniji naziv.",
        "randomrootpage": "Slučajna root stranica",
        "log-action-filter-block": "Vrsta blokiranja:",
        "log-action-filter-delete": "Vrsta brisanja:",
index d3c0ed4..ac9bf27 100644 (file)
        "createaccountreason": "Motiu:",
        "createacct-reason": "Motiu",
        "createacct-reason-ph": "Per què creeu un altre compte",
+       "createacct-reason-help": "Missatge mostrat en el registre de creació de comptes",
        "createacct-submit": "Crea el meu compte",
        "createacct-another-submit": "Crea un compte",
        "createacct-continue-submit": "Continua amb la creació del compte",
        "botpasswords-updated-title": "Contrasenya de bot actualitzada",
        "botpasswords-not-exist": "L'usuari «$1» no té una contrasenya de bot anomenada «$2».",
        "resetpass_forbidden": "No poden canviar-se les contrasenyes",
+       "resetpass_forbidden-reason": "Les contrasenyes no es poden canviar: $1",
        "resetpass-no-info": "Heu d'estar registrats en un compte per a poder accedir directament a aquesta pàgina.",
        "resetpass-submit-loggedin": "Canvia la contrasenya",
        "resetpass-submit-cancel": "Cancel·la",
        "confirm-watch-top": "Voleu afegir aquesta pàgina a la llista de seguiment?",
        "confirm-unwatch-button": "D'acord",
        "confirm-unwatch-top": "Voleu treure aquesta pàgina de la llista de seguiment?",
+       "confirm-rollback-button": "D'acord",
+       "confirm-rollback-top": "Voleu revertir les modificacions a la pàgina?",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← pàgina anterior",
        "imgmultipagenext": "pàgina següent →",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "la pàgina no existeix encara",
        "mw-widgets-titleinput-description-redirect": "redirigeix a $1",
-       "api-error-blacklisted": "Trieu un títol diferent, més descriptiu.",
        "sessionmanager-tie": "No es poden combinar diferents tipus de sol·licituds d'autenticació: $1.",
        "sessionprovider-generic": "$1 sessions",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessions basades en galetes",
        "randomrootpage": "Pàgina arrel aleatòria",
        "log-action-filter-block": "Tipus de blocatge:",
        "log-action-filter-delete": "Tipus de supressió:",
+       "log-action-filter-import": "Tipus d'importació:",
+       "log-action-filter-managetags": "Tipus d'acció de gestió d'etiquetes:",
+       "log-action-filter-move": "Tipus de reanomenament:",
+       "log-action-filter-newusers": "Tipus de creació de compte:",
        "log-action-filter-patrol": "Tipus de patrullatge:",
        "log-action-filter-protect": "Tipus de protecció:",
+       "log-action-filter-rights": "Tipus de canvi de permisos:",
+       "log-action-filter-suppress": "Tipus de supressió:",
        "log-action-filter-upload": "Tipus de càrrega:",
        "log-action-filter-all": "Tota",
        "log-action-filter-block-block": "Bloca",
        "authmanager-authn-autocreate-failed": "Ha fallat la creació automàtica d'un compte local: $1",
        "authmanager-realname-label": "Nom real",
        "authmanager-realname-help": "Nom real de l'usuari",
+       "authmanager-provider-temporarypassword": "Contrasenya temporal",
        "authprovider-resetpass-skip-label": "Omet",
        "authpage-cannot-login-continue": "No es pot continuar amb l'inicio de sessió. Probablement la vostra sessió ha expirat.",
        "authpage-cannot-create-continue": "No es pot prosseguir la creació del compte. Probablement la vostra sessió ha expirat.",
        "changecredentials": "Canvi de dades credencials",
        "changecredentials-submit": "Canvia les dades credencials",
        "credentialsform-provider": "Tipus de dades credencials:",
-       "credentialsform-account": "Nom del compte:"
+       "credentialsform-account": "Nom del compte:",
+       "linkaccounts-submit": "Enllaça els comptes",
+       "unlinkaccounts": "Desenllaça els comptes",
+       "unlinkaccounts-success": "El compte s'ha desenllaçat.",
+       "authenticationdatachange-ignored": "No s'ha gestionat el canvi de dades d'autenticació. Potser no s'ha configurat cap proveïdor?"
 }
index 20b196f..5214d3f 100644 (file)
@@ -31,7 +31,8 @@
                        "Urbanecm",
                        "LordMsz",
                        "Matma Rex",
-                       "Dvorapa"
+                       "Dvorapa",
+                       "Walter Klosse"
                ]
        },
        "tog-underline": "Podtrhávat odkazy:",
        "content-model-css": "CSS",
        "content-json-empty-object": "Prázdný objekt",
        "content-json-empty-array": "Prázdné pole",
+       "deprecated-self-close-category": "Stránky s neplatnými sebeuzavírajícími se HTML značkami",
+       "deprecated-self-close-category-desc": "Stránka obsahuje neplatné sebeuzavírající se HTML značky, například <code>&lt;b/></code> nebo <code>&lt;span/></code>. Jejich chování se v zájmu konzistence se specifikací HTML5 brzy změní, proto je jejich použití ve wikitextu zastaralé.",
        "duplicate-args-warning": "<strong>Upozornění:</strong> Stránka [[:$1]] volá [[:$2]] s více než jednou hodnotou parametru „$3“. Použije se jen poslední uvedená hodnota.",
        "duplicate-args-category": "Stránky s duplicitními argumenty ve voláních šablon",
        "duplicate-args-category-desc": "Stránka obsahuje volání šablony, které používá duplicitní argumenty, např. <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> nebo <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "tooltip-namespace_association": "Zaškrtnutím tohoto políčka zahrnete i diskusní či obsahový jmenný prostor příslušný k vybranému jmennému prostoru",
        "blanknamespace": "(Hlavní)",
        "contributions": "Příspěvky {{GENDER:$1|uživatele|uživatelky}}",
-       "contributions-title": "Příspěvky uživatele $1",
+       "contributions-title": "Příspěvky {{GENDER:$1|uživatele|uživatelky|uživatele/uživatelky}} $1",
        "mycontris": "Příspěvky",
        "anoncontribs": "Příspěvky",
        "contribsub2": "{{GENDER:$3|uživatele|uživatelky}} $1 ($2)",
        "mw-widgets-dateinput-placeholder-month": "RRRR-MM",
        "mw-widgets-titleinput-description-new-page": "stránka zatím neexistuje",
        "mw-widgets-titleinput-description-redirect": "přesměrování na $1",
-       "api-error-blacklisted": "Zvolte prosím jiný, popisný název.",
        "sessionmanager-tie": "Nelze kombinovat několik typů autentizace požadavků: $1.",
        "sessionprovider-generic": "relace pomocí $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "relace pomocí cookies",
index 9249abf..f01e18d 100644 (file)
@@ -99,7 +99,7 @@
        "tog-extendwatchlist": "Alle und nicht nur die aktuellsten Änderungen in der Beobachtungsliste anzeigen",
        "tog-usenewrc": "Änderungen auf „Letzte Änderungen“ und der Beobachtungsliste nach Seite gruppieren",
        "tog-numberheadings": "Überschriften automatisch nummerieren",
-       "tog-showtoolbar": "Bearbeiten-Werkzeugleiste anzeigen",
+       "tog-showtoolbar": "Bearbeiten-Werkzeugleiste aktivieren",
        "tog-editondblclick": "Seiten mit Doppelklick bearbeiten",
        "tog-editsectiononrightclick": "Einzelne Abschnitte per Rechtsklick bearbeiten",
        "tog-watchcreations": "Selbst erstellte Seiten und hochgeladene Dateien automatisch beobachten",
        "databaseerror-query": "Abfrage: $1",
        "databaseerror-function": "Funktion: $1",
        "databaseerror-error": "Fehler: $1",
-       "transaction-duration-limit-exceeded": "Um eine große Verzögerung in der Datenreplikation zu vermeiden, wurde diese Transaktion abgebrochen. Die Schreibdauer ($1) hat die Grenze von {{PLURAL:$2|einer Sekunde|$2 Sekunden}} überschritten. Falls du viele Objekte auf einmal änderst, versuche stattdessen, die Änderungen auf mehrere Operationen aufzuteilen.",
+       "transaction-duration-limit-exceeded": "Um eine große Verzögerung in der Datenreplikation zu vermeiden, wurde diese Transaktion abgebrochen. Die Schreibdauer ($1) hat die Grenze von $2 Sekunden überschritten. Falls du viele Objekte auf einmal änderst, versuche stattdessen, die Änderungen auf mehrere Operationen aufzuteilen.",
        "laggedslavemode": "<strong>Achtung:</strong> Die angezeigte Seite könnte unter Umständen nicht die letzten Bearbeitungen enthalten.",
        "readonly": "Datenbank gesperrt",
        "enterlockreason": "Bitte gib einen Grund ein, warum die Datenbank gesperrt werden soll und eine Abschätzung über die Dauer der Sperrung",
        "content-model-css": "CSS",
        "content-json-empty-object": "Leeres Objekt",
        "content-json-empty-array": "Leeres Array",
+       "deprecated-self-close-category": "Seiten, die ungültige selbstschließende HTML-Tags verwenden",
+       "deprecated-self-close-category-desc": "Die Seite enthält ungültige selbstschließende HTML-Tags wie <code>&lt;b/></code> oder <code>&lt;span/></code>. Das Verhalten dieser Tags wird bald geändert, um mit der HTML5-Spezifikation konsistent zu sein, so dass ihre Verwendung im Wikitext veraltet ist.",
        "duplicate-args-warning": "<strong>Warnung:</strong> [[:$1]] ruft [[:$2]] mit mehr als einem Wert für den Parameter „$3“ auf. Nur der letzte angegebene Wert wird verwendet.",
        "duplicate-args-category": "Seiten, die doppelte Argumente in Vorlagenaufrufen verwenden",
        "duplicate-args-category-desc": "Die Seite enthält Vorlagenaufrufe, die Duplikate von Argumenten verwenden, wie <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> oder <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "prefs-namespaces": "Namensräume",
        "default": "Voreinstellung",
        "prefs-files": "Dateien",
-       "prefs-custom-css": "Benutzerdefinierte CSS",
+       "prefs-custom-css": "Benutzerdefiniertes CSS",
        "prefs-custom-js": "Benutzerdefiniertes JavaScript",
        "prefs-common-css-js": "Gemeinsames CSS/JavaScript aller Benutzeroberflächen:",
        "prefs-reset-intro": "Du kannst diese Seite verwenden, um die Einstellungen auf die Standards zurückzusetzen.\nDies kann nicht mehr rückgängig gemacht werden.",
        "creditspage": "Seitenzuschreibung",
        "nocredits": "Für diese Seite sind keine Zuschreibungen vorhanden.",
        "spamprotectiontitle": "Spamschutzfilter",
-       "spamprotectiontext": "Der Text, die du speichern willst, wurde vom Spamschutzfilter blockiert.\nDas liegt wahrscheinlich an einem Link auf eine externe Seite.",
+       "spamprotectiontext": "Der Text, den du speichern möchtest, wurde vom Spamschutzfilter blockiert.\nDas liegt wahrscheinlich an einem Link auf eine externe Seite.",
        "spamprotectionmatch": "'''Der folgende Text wurde vom Spamfilter gefunden: ''$1'''''",
        "spambot_username": "MediaWiki-Spam-Säuberung",
        "spam_reverting": "Letzte Version ohne Links zu $1 wiederhergestellt.",
        "mw-widgets-dateinput-placeholder-month": "JJJJ-MM",
        "mw-widgets-titleinput-description-new-page": "Seite ist noch nicht vorhanden",
        "mw-widgets-titleinput-description-redirect": "Weiterleitung nach $1",
-       "api-error-blacklisted": "Bitte einen anderen, aussagekräftigen Titel wählen.",
        "sessionmanager-tie": "Mehrere Anfrageauthentifikationstypen konnten nicht kombiniert werden: $1.",
        "sessionprovider-generic": "$1-Sitzungen",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "cookiebasierten Sitzungen",
        "log-action-filter-newusers": "Typ der Benutzerkontenerstellung:",
        "log-action-filter-patrol": "Kontrolltyp:",
        "log-action-filter-protect": "Schutztyp:",
-       "log-action-filter-rights": "Typ der Rechteänderung",
-       "log-action-filter-suppress": "Unterdrückungstyp",
+       "log-action-filter-rights": "Typ der Rechteänderung:",
+       "log-action-filter-suppress": "Unterdrückungstyp:",
        "log-action-filter-upload": "Hochladetyp:",
        "log-action-filter-all": "Alle",
        "log-action-filter-block-block": "Sperren",
index beeea38..e16eca1 100644 (file)
        "category-empty": "''Ena kategoriye de hewna qet nuştey ya zi medya çıniyê.''",
        "hidden-categories": "{{PLURAL:$1|Kategoriya nımıtiye|Kategoriyê nımıtey}}",
        "hidden-category-category": "Kategoriyê nımıtey",
-       "category-subcat-count": "{{PLURAL:$2|Na kategoriya de $1 bınkategoriyay estê.|$2 kategoriyan ra $1 bınkategoriyay asenê.}}",
+       "category-subcat-count": "{{PLURAL:$2|Na kategoriya de $1 bınkategoriyay estê.|$2 kategoriyan ra $1 bınkategoriyay asenê.}} \n(K) Kategori (D) Dosya (P) Pela",
        "category-subcat-count-limited": "Na kategoriya de {{PLURAL:$1|ena kategoriya bınên est a|enê $1 kategoriyay bınêni est ê}}.",
        "category-article-count": "{{PLURAL:$2|Na kategoriye de teyna ena pele esta.|Ebe $2 ra pêro piya {{PLURAL:$1|ena pela na kategoriye dera|$1 enê peli na kategoriye derê.}}}}",
        "category-article-count-limited": "{{PLURAL:$1|Pela cêrêne|$1 Pelê cêrêni}} na kategoriye derê.",
        "minoredit": "No yew vurnayışo werdiyo",
        "watchthis": "Ena pele seyr ke",
        "savearticle": "Pele qeyd ke",
+       "savechanges": "Vurnayışan qeyd ke",
        "publishpage": "Perer bıhesırne",
+       "publishchanges": "Vurnayışa vıla ke",
        "preview": "Verqayt",
        "showpreview": "Verqayti bıasne",
        "showdiff": "Vurriyayışan bıasne",
        "search-category": "(kategori $1)",
        "search-file-match": "(zerreyê dosya yewbini gêno)",
        "search-suggest": "To va: $1",
-       "search-rewritten": "Neticey $ ra asenê.  Herunda ney wa neticey $2 ra bıasê",
+       "search-rewritten": "Neticey $ ra asenê.  Herunda ney wa neticey $2 ra bıasê?",
        "search-interwiki-caption": "Proceyê bıray",
        "search-interwiki-default": "$1 ra neticey:",
        "search-interwiki-more": "(véşi)",
        "prefs-help-recentchangescount": "Ney de vurnayışê peyêni, tarixê pelan u cıkewteni asenê.",
        "prefs-help-watchlist-token2": "Na pawıtış nımnayi kılta listada şımaya.\nOke kıliti zano şeno listeya tamaşann bıvino. Poğta coy ra kesiya me hesırne. \n[[Special:ResetTokens|Na kıliti reset kerdışi re tiyay bıploğne]].",
        "savedprefs": "Tecihê şıma qeyd biy.",
+       "savedrights": "Qandé {{GENDER:$1|$1}} heqê karberi qeyd  biye.",
        "timezonelegend": "Warey saete:",
        "localtime": "saeta mehelliye:",
        "timezoneuseserverdefault": "Zey karkerdışê Wiki ($1)",
        "badsig": "Îmzayê tu raşt niyo.\nEtiketê HTMLî kontrol bike.",
        "badsiglength": "İmzaya şıma zaf derga.\nA gani be $1 {{PLURAL:$1|karakter|karakteran}} ra zêde mebo.",
        "yourgender": "Şeklê xitabi?",
-       "gender-unknown": "Ez detay nivana",
+       "gender-unknown": "Çımhal tı kerdê etiket, Nusner do çekuya Nerimaki cinsiyeti de şeno bıkar no",
        "gender-male": "Perané wiki camérd deyne ezo vırnena",
        "gender-female": "Perané wiki cıni deyne eza vırnena",
        "prefs-help-gender": "Na tercih keyfiya.\nNa nustenek ercana qısan de qandé grameri karneyéna, na malumater herkes şeno bıvino .",
        "right-passwordreset": "E-postayanê parola reset kerdışa vineno",
        "right-managechangetags": "[[Special:Tags|Etiketi]] vıraz u aktiv (me)ke",
        "right-applychangetags": "[[Special:Tags|Etiketa]]  vurnayışana piya dezge fi.",
+       "grant-editmyoptions": "Tercihanê xo bıvurne",
+       "grant-editmywatchlist": "Listeyseyran de xo bıvırne",
+       "grant-editpage": "Peran bıvurnê",
+       "grant-editprotected": "Srar bıyaye peran bıvurnê",
        "newuserlogpage": "Cıkewtışê hesabvıraştışi",
        "newuserlogpagetext": "Ena log de viraştişê karberî esta.",
        "rightslog": "Qeydê heqanê karberi",
        "special-characters-title-minus": "işaretê kemiye",
        "mw-widgets-dateinput-placeholder-day": "SSSS-AA-RR",
        "mw-widgets-dateinput-placeholder-month": "SSSS-AA",
-       "mw-widgets-titleinput-description-redirect": "berd be $1",
-       "api-error-blacklisted": "Reca keme zewbina weçine, name wa şınasnaye bo."
+       "mw-widgets-titleinput-description-redirect": "berd be $1"
 }
index dca9160..30421d7 100644 (file)
        "minoredit": "यो नानो सम्पादन हो",
        "watchthis": "यै पानाको ध्यान राख",
        "savearticle": "सङ्ग्रह गर",
+       "savechanges": "परिवर्तन सुरक्षित गर",
        "publishpage": "प्रकाशित पृष्ठ",
+       "publishchanges": "परिवर्तन प्रकाशित गर",
        "preview": "पूर्वावलोकन",
        "showpreview": "पूर्वालोकन धेकाउन्या",
        "showdiff": "परिवर्तन धेकाउन्या",
        "anoneditwarning": "<strong>चेतावनी:</strong> तमले प्रवेश अरेको नाइथिन । तमरो आइपि ठेगाना पाना सम्पादन इतिहासमि दर्ता गरिन्या छ र यो सब्बैले हेद्द सक्कान । यदि तमलाईँ <strong>[$1 लगईन]</strong> वा <strong>[$2 नयाँ खाता बनाउन्या] गर्याभण्या तमबठे गरियाको सम्पादन तमरो प्रयोगकर्तानाममि जोडिन्याछ ।",
        "missingsummary": "'''यादगर्या :''' तमीले सम्पादन सारांश दियाका छैनौ ।\nयदि तमीले \"{{int:savearticle}}\"  थिच्यौ भण्या , सारांश बिना नै सङ्ग्रहित गरिन्या छ ।",
        "selfredirect": "<strong>चेतावनी:</strong> तम यै पानालाई आफुमी पुनः निर्देशित गद्द लाग्याछौ ।\nहुनसक्छ तम अनुप्रेषितको लागि गलत लक्ष्य निर्दिष्ट गद्द लाग्याछौ, वा गलत पानाको सम्पादन गद्द लाग्याछौ ।\nतम पुनः एकपल्ट \"{{int:savearticle}}\" क्लिक गद्दाछौ, पुनः निर्देशित तसै लै बनाइन्याछ।",
-       "missingcommentheader": "'''याद गर :''' तमीले टिप्पणीमी विषय /शीर्ष पंक्ति  दियाका छैनौ ।\nतमीले फेरि \"{{int:savearticle}}\"  थिच्यौ भण्या , तमरो सम्पादन यसै रुपमी संग्रहित हुन्याछ ।",
+       "missingcommenttext": "कृपया तलतिर टिप्पणी राख ।",
+       "missingcommentheader": "'''याद गर :''' तमले टिप्पणीमी विषय /शीर्ष पंक्ति  दियाका छैनौ ।\nतमले फेरि \"{{int:savearticle}}\"  थिच्यौ भण्या , तमरो सम्पादन यसै रुपमी संग्रहित हुन्याछ ।",
        "summary-preview": "सारांश पूर्वालोकन:",
        "subject-preview": "विषय पूर्वरुप:",
        "previewerrortext": "तमरो परिवर्तनको पूर्वावलोकन बनाउन खोज्दा समस्या आयाको छ ।",
        "yournick": "नयाँ हस्ताक्षर:",
        "prefs-help-signature": "कुरडी पानाका टिप्पणीहरू \"<nowiki>~~~~</nowiki>\" द्वारा दस्तखत गरिनुपडन्छ ,त्यो पछि तमरो दस्तखत र समयरेखामी रुपान्तरित हुनेछ ।",
        "badsiglength": "तमरो दस्तखत मैथै लामो छ।\nयो $1 {{PLURAL:$1|अक्षर|अक्षरहरू}} भन्दा लामो हुनु हुँदैन ।",
+       "gender-male": "उ विकि पृष्ठहरू सम्पादन गरन्छ",
+       "gender-female": "तीन विकि पृष्ठहरु गरिन्छिन",
        "email": "ईमेल",
        "prefs-help-realname": "वास्तविक नाम ऐच्छिक हो ।\nतमीले खुलायौ भण्या तमरो कामको श्रेय दिनको लेखा यैको प्रयोग गरिन्या छ ।",
        "prefs-help-email-required": "इमेल ठेगाना चाहिन्छ ।",
        "grouppage-autoconfirmed": "{{एनयस:आयोजना}}:स्वनिर्धारित प्रयोगकर्ताहरू",
        "grouppage-bot": "{{एनयस:आयोजना}}:बोटहरु",
        "grouppage-sysop": "{{एनयस:आयोजना}}:प्रबन्धकहरु",
-       "grouppage-bureaucrat": "{{à¤\8fनयस:à¤\86यà¥\8bà¤\9cना}}:पà¥\8dरशासà¤\95हरà¥\81",
+       "grouppage-bureaucrat": "{{à¤\8fनयस:à¤\86यà¥\8bà¤\9cना}}:पà¥\8dरशासà¤\95हरà¥\82",
        "grouppage-suppress": "{{एनयस:आयोजना}}:लुकौन्या",
        "right-read": "पृष्ठहरू पढ",
        "right-edit": "पृष्ठहरू सम्पादन गर",
        "right-deletedtext": "मेट्याका संशोधन बीचका मेट्याका पाठ र परिवर्तनहरू हेद्या",
        "right-suppressionlog": "व्यक्तिगत लगहरू हेद्या",
        "right-block": "अरु प्रयोगकर्तानलाई सम्पादन गद्दाकी ब्लक गर",
+       "right-unblockself": "आफुलाई खुल्ला गर ।",
        "right-editprotected": "\"{{int:protect-level-sysop}}\" को हैसियतले सुरक्षित पानाहरू सम्पादन गद्या",
        "right-editusercssjs": "अन्य प्रयोगकर्ताको सी.एस.एस. रे जाभास्क्रिप्ट फाइलहरू सम्पादन गद्या",
        "right-editusercss": "अन्य प्रयोगकर्ताको सी. एस. एस. फाइलहरू सम्पादन गद्या",
index 5a232c8..c1bba97 100644 (file)
@@ -48,7 +48,8 @@
                        "Gts-tg",
                        "Nemo bis",
                        "Αντιγόνη",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Ανώνυμος Βικιπαιδιστής"
                ]
        },
        "tog-underline": "Υπογράμμιση συνδέσμων:",
        "mw-widgets-dateinput-placeholder-month": "ΕΕΕΕ-ΜΜ",
        "mw-widgets-titleinput-description-new-page": "η σελίδα που δεν υπάρχει ακόμα",
        "mw-widgets-titleinput-description-redirect": "ανακατεύθυνση στο $1",
-       "api-error-blacklisted": "Παρακαλώ επιλέξτε ένα διαφορετικό, περιγραφικό τίτλο.",
        "sessionprovider-generic": "$1 συνεδρίες",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "συνεδρίες με βάση τα cookies",
        "sessionprovider-nocookies": "Τα Cookies μπορούν να απενεργοποιηθούν. Βεβαιωθείτε ότι έχετε ενεργοποιημένα τα cookies και ξεκινήστε πάλι.",
-       "randomrootpage": "Τυχαία κύρια σελίδα"
+       "randomrootpage": "Τυχαία κύρια σελίδα",
+       "log-action-filter-rights": "Πληκτρολογήστε για αλλαγή δικαιωμάτων:"
 }
index 982371b..6d1e58d 100644 (file)
        "databaseerror-query": "Query: $1",
        "databaseerror-function": "Function: $1",
        "databaseerror-error": "Error: $1",
-       "transaction-duration-limit-exceeded": "To avoid creating high replication lag, this transaction was aborted because the write duration ($1) exceeded the $2 {{PLURAL:$2|second|seconds}} limit.\nIf you are changing many items at once, try doing multiple smaller operations instead.",
+       "transaction-duration-limit-exceeded": "To avoid creating high replication lag, this transaction was aborted because the write duration ($1) exceeded the $2 second limit.\nIf you are changing many items at once, try doing multiple smaller operations instead.",
        "laggedslavemode": "<strong>Warning:</strong> Page may not contain recent updates.",
        "readonly": "Database locked",
        "enterlockreason": "Enter a reason for the lock, including an estimate of when the lock will be released",
        "content-model-json": "JSON",
        "content-json-empty-object": "Empty object",
        "content-json-empty-array": "Empty array",
+       "deprecated-self-close-category": "Pages using invalid self-closed HTML tags",
+       "deprecated-self-close-category-desc": "The page contains invalid self-closed HTML tags, such as <code>&lt;b/></code> or <code>&lt;span/></code>.  The behavior of these will change soon to be consistent with the HTML5 specification, so their use in wikitext is deprecated.",
        "duplicate-args-warning": "<strong>Warning:</strong> [[:$1]] is calling [[:$2]] with more than one value for the \"$3\" parameter. Only the last value provided will be used.",
        "duplicate-args-category": "Pages using duplicate arguments in template calls",
        "duplicate-args-category-desc": "The page contains template calls that use duplicates of arguments, such as <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "YYYY-MM",
        "mw-widgets-titleinput-description-new-page": "page does not exist yet",
        "mw-widgets-titleinput-description-redirect": "redirect to $1",
-       "api-error-blacklisted": "Please choose a different, descriptive title.",
        "sessionmanager-tie": "Cannot combine multiple request authentication types: $1.",
        "sessionprovider-generic": "$1 sessions",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "cookie-based sessions",
index 0a5d3c7..1a60284 100644 (file)
                        "Xð",
                        "Robin van der Vliet",
                        "Zciric",
-                       "Psychoslave"
+                       "Psychoslave",
+                       "Orikrin1998"
                ]
        },
        "tog-underline": "Substreki ligilojn",
        "tog-hideminor": "Kaŝi malgrandajn redaktetojn ĉe <i>Lastaj ŝanĝoj</i>",
        "tog-hidepatrolled": "Kaŝi patrolitajn redaktojn en lastaj ŝanĝoj",
        "tog-newpageshidepatrolled": "Kaŝi patrolitajn paĝojn de listo de novaj paĝoj",
-       "tog-hidecategorization": "Kaŝu enkategoriigon de paĝoj",
+       "tog-hidecategorization": "Kaŝi enkategoriigon de paĝoj",
        "tog-extendwatchlist": "Etendi la atentaron por montri ĉiujn ŝanĝojn, ne nur la plej lastajn",
        "tog-usenewrc": "Grupigi ŝanĝojn laŭ paĝo en \"Lastaj ŝanĝoj\" kaj \"Atentaro\" (bezonas Ĝavaskripton)",
-       "tog-numberheadings": "Aŭtomate numerigi sekciojn",
+       "tog-numberheadings": "Aŭtomate numeri sekciojn",
        "tog-showtoolbar": "Montri redakto-breton (per Ĝavaskripto)",
        "tog-editondblclick": "Redakti paĝojn per duobla alklako",
        "tog-editsectiononrightclick": "Ŝalti sekcian redaktadon per dekstra musklako de sekciaj titoloj (per Ĝavaskripto)",
@@ -64,7 +65,7 @@
        "tog-watchdefault": "Aldoni al mia atentaro paĝojn kaj dosierojn redaktitajn de mi",
        "tog-watchmoves": "Aldoni paĝojn kaj dosierojn, kiujn mi movas, al mia atentaro",
        "tog-watchdeletion": "Aldoni paĝojn kaj dosierojn, kiujn mi forigas, al mia atentaro",
-       "tog-watchuploads": "Aldonu novajn dosierojn ke mi alŝutas al mia atentaro",
+       "tog-watchuploads": "Aldonu novajn dosierojn, kiujn mi alŝutas, al mia atentaro",
        "tog-watchrollback": "Aldoni paĝojn, kie mi amasmalfaris, al mia atentaro.",
        "tog-minordefault": "Marki defaŭlte ĉiujn redaktojn kiel etajn",
        "tog-previewontop": "Montri antaŭrigardon antaŭ redaktilo",
@@ -82,7 +83,7 @@
        "tog-watchlisthidebots": "Kaŝi robotajn redaktojn de la atentaro",
        "tog-watchlisthideminor": "Kaŝi malgrandajn redaktojn de la atentaro",
        "tog-watchlisthideliu": "Kaŝi redaktojn de ensalutitaj uzantoj de la atentaro",
-       "tog-watchlistreloadautomatically": "Reŝarĝi la atentaron aŭtomate ĉiam filtro estas ŝanĝita (Necesi Ĝavoskripton)",
+       "tog-watchlistreloadautomatically": "Reŝargi la atentaron aŭtomate ĉiam, kiam filtrilo estas ŝanĝita (bezonas Ĝavoskripton)",
        "tog-watchlisthideanons": "Kaŝi redaktojn de anonimuloj de la atentaro",
        "tog-watchlisthidepatrolled": "Kaŝi patrolitajn redaktojn de la atentaro",
        "tog-watchlisthidecategorization": "Kaŝu enkategoriigon de paĝoj",
        "pagecategories": "{{PLURAL:$1|Kategorio|Kategorioj}}",
        "category_header": "Artikoloj en kategorio \"$1\"",
        "subcategories": "Subkategorioj",
-       "category-media-header": "Dosieroj en kategorio \"$1\"",
+       "category-media-header": "Dosieroj en kategorio “$1”",
        "category-empty": "<em>Tiu ĉi kategorio nuntempe enhavas neniun artikolon aŭ plurmedian dosieron.</em>",
        "hidden-categories": "{{PLURAL:$1|Kaŝita kategorio|Kaŝitaj kategorioj}}",
        "hidden-category-category": "Kaŝitaj kategorioj",
        "createacct-reason": "Kialo",
        "createacct-reason-ph": "Kial vi kreas plian konton",
        "createacct-reason-help": "Mesaĝo vidigita en la protokolo pri kreado de konto",
-       "createacct-submit": "Krei konton",
+       "createacct-submit": "Kreu vian konton",
        "createacct-another-submit": "Krei konton",
        "createacct-continue-submit": "Daŭri kreadon de konto",
        "createacct-another-continue-submit": "Daŭri kreadon de konto",
        "minoredit": "Ĉi tiu ŝanĝo estas redakteto",
        "watchthis": "Atenti ĉi tiun paĝon",
        "savearticle": "Konservi paĝon",
+       "savechanges": "Konservi ŝanĝojn",
        "publishpage": "Publikigi paĝon",
        "preview": "Antaŭrigardo",
        "showpreview": "Antaŭrigardo",
        "rev-suppressed-unhide-diff": "Unu el la revizioj de ĉi tiu diferenco estis '''kaŝita'''.\nEble estas detaloj en la [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} protokolo pri kaŝado].\nVi povas ankoraŭ [$1 vidi ĉi tiun diferencon] se vi deziras.",
        "rev-deleted-diff-view": "Unu el la revizioj de ĉi tiu diferenco estis '''forigita'''.\nVi povas rigardi ĉi tiun diferencon, detaloj estas trovebla en la [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} protokolo pri forigado].",
        "rev-suppressed-diff-view": "Unu el la revizioj de ĉi tiu diferenco estis '''kaŝita'''.\nKiel administranto, vi povas rigardi ĉi tiun diferencon, eble estas detaloj en la [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} protokolo pri kaŝadoj].",
-       "rev-delundel": "montri/kaŝi",
+       "rev-delundel": "ŝanĝi videblecon",
        "rev-showdeleted": "montri",
        "revisiondelete": "Forigi/malforigi versiojn",
        "revdelete-nooldid-title": "Nevalida cela revizio",
        "mergelog": "Protokolo de kunigoj",
        "revertmerge": "Malkunigi",
        "mergelogpagetext": "Jen listo de la plej lastatempaj kunigoj de unu paĝhistorio en alian.",
-       "history-title": "Revizio-historio de \"$1\"",
+       "history-title": "Revizio-historio de “$1”",
        "difference-title": "$1: Malsamoj inter versioj",
        "difference-title-multipage": "Malsamoj inter la paĝoj $1 kaj $2",
        "difference-multipage": "(Diferenco inter paĝoj)",
        "searchprofile-images": "Plurmedio",
        "searchprofile-everything": "Ĉion",
        "searchprofile-advanced": "Progresa",
-       "searchprofile-articles-tooltip": "Serĉo en $1",
+       "searchprofile-articles-tooltip": "Serĉi en $1",
        "searchprofile-images-tooltip": "Serĉi dosierojn",
        "searchprofile-everything-tooltip": "Traserĉi ĉiun enhavon (inkluzivante diskuto-paĝojn)",
        "searchprofile-advanced-tooltip": "Serĉi en specialaj nomspacoj",
        "tooltip-pt-watchlist": "Listo de paĝoj kies ŝanĝojn vi priatentas.",
        "tooltip-pt-mycontris": "Listo de viaj kontribuoj",
        "tooltip-pt-anoncontribs": "Listo de redaktoj faritaj el ĉi tiu IPa adreso",
-       "tooltip-pt-login": "Vi estas invitita ensaluti, tamen ne estas devige.",
+       "tooltip-pt-login": "Vi kuraĝigas ensaluti, tamen ne estas devige.",
        "tooltip-pt-logout": "Elsaluti",
        "tooltip-pt-createaccount": "Ni rekomendas al vi kreon de uzantokonto kaj ensaluto; tamen, tio ne estas deviga",
        "tooltip-ca-talk": "Diskuto pri la artikolo",
        "tooltip-ca-nstab-project": "Rigardi la paĝon de la projekto",
        "tooltip-ca-nstab-image": "Rigardi la dosierpaĝon",
        "tooltip-ca-nstab-mediawiki": "Rigardi la sisteman mesaĝon",
-       "tooltip-ca-nstab-template": "Rigardi la ŝablonon",
+       "tooltip-ca-nstab-template": "Vidi la ŝablonon",
        "tooltip-ca-nstab-help": "Rigardi la helppaĝon",
        "tooltip-ca-nstab-category": "Vidi la paĝon de la kategorio",
        "tooltip-minoredit": "Marki tiun ŝanĝon kiel etan",
        "tooltip-save": "Konservi viajn ŝanĝojn",
        "tooltip-publish": "Publikigi viajn ŝanĝojn",
-       "tooltip-preview": "Antaŭrigardi viajn ŝanĝojn. Bonvolu uzi tion antaŭ ol konservi ilin!",
+       "tooltip-preview": "Antaŭrigardi viajn ŝanĝojn. Bonvolu uzi tion antaŭ ol konservi.",
        "tooltip-diff": "Montri la ŝanĝojn kiujn vi faris de la teksto.",
        "tooltip-compareselectedversions": "Rigardi la malsamojn inter ambaŭ selektitaj versioj de ĉi tiu paĝo.",
        "tooltip-watch": "Aldoni ĉi paĝon al via atentaro",
        "mw-widgets-dateinput-placeholder-month": "JJJJ-MM",
        "mw-widgets-titleinput-description-new-page": "paĝo ankoraŭ ne ekzistas",
        "mw-widgets-titleinput-description-redirect": "alidirekti al $1",
-       "api-error-blacklisted": "Bonvolu elekti alian, priskriban titolon.",
        "sessionmanager-tie": "Kombini diversajn tipojn de ensaluta peto ne estas permisita: $1.",
        "sessionprovider-generic": "$1 seancoj",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "kuketaj seancoj",
index 63427e4..9215593 100644 (file)
                        "2axterix2",
                        "Matma Rex",
                        "Dgstranz",
-                       "Copper12"
+                       "Copper12",
+                       "Ivanhercaz",
+                       "AlvaroMolina"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "unprotectthispage": "Cambiar la protección de esta página",
        "newpage": "Página nueva",
        "talkpage": "Discutir esta página",
-       "talkpagelinktext": "Discusión",
+       "talkpagelinktext": "discusión",
        "specialpage": "Página especial",
        "personaltools": "Herramientas personales",
        "articlepage": "Ver artículo",
        "views": "Vistas",
        "toolbox": "Herramientas",
        "userpage": "Ver página de usuario",
-       "projectpage": "Ver página de proyecto",
+       "projectpage": "Ver página del proyecto",
        "imagepage": "Ver página del archivo",
-       "mediawikipage": "Ver página de mensaje",
+       "mediawikipage": "Ver página del mensaje",
        "templatepage": "Ver página de plantilla",
        "viewhelppage": "Ver página de ayuda",
        "categorypage": "Ver página de categoría",
        "content-model-css": "CSS",
        "content-json-empty-object": "Objeto vacío",
        "content-json-empty-array": "Matriz vacía",
+       "deprecated-self-close-category": "Páginas que utilizan etiquetas HTML autocerradas no válidas",
+       "deprecated-self-close-category-desc": "Esta página contiene etiquetas HTML de auto-cierre invalidas, tales como <code>&lt;b/></code> o <code>&lt;span/></code>. El comportamiento de estas en  cambiará pronto para ser coherente con la especificación de HTML5, por lo que su utilización en wikitext está en desuso.",
        "duplicate-args-warning": "<strong>Aviso:</strong> [[:$1]] llama a [[:$2]] con más de un valor para el parámetro «$3». Se usará solo el último valor proporcionado.",
        "duplicate-args-category": "Páginas que usan argumentos duplicados en invocaciones de plantillas",
        "duplicate-args-category-desc": "La página contiene invocaciones de plantillas que utilizan argumentos duplicados, como <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> o <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "la página aún no existe",
        "mw-widgets-titleinput-description-redirect": "redirigir a $1",
-       "api-error-blacklisted": "Elige un título diferente, más descriptivo.",
        "sessionmanager-tie": "No se pueden combinar múltiples tipos de autenticación de solicitudes: $1.",
        "sessionprovider-generic": "sesiones $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sesiones basadas en cookies",
        "log-action-filter-newusers": "Tipo de creación de la cuenta:",
        "log-action-filter-patrol": "Tipo de verificación:",
        "log-action-filter-protect": "Tipo de protección:",
-       "log-action-filter-rights": "El tipo de cambio correcto",
-       "log-action-filter-suppress": "Tipo de supresión",
+       "log-action-filter-rights": "Tipo de cambio de permisos:",
+       "log-action-filter-suppress": "Tipo de supresión:",
        "log-action-filter-upload": "Tipo de subida:",
        "log-action-filter-all": "Todas",
        "log-action-filter-block-block": "Bloquear",
index 97e943e..1b5d5e7 100644 (file)
        "october-date": "$1. oktoober",
        "november-date": "$1. november",
        "december-date": "$1. detsember",
+       "period-am": "e. l.",
+       "period-pm": "p. l.",
        "pagecategories": "{{PLURAL:$1|Kategooria|Kategooriad}}",
        "category_header": "Leheküljed kategoorias \"$1\"",
        "subcategories": "Alamkategooriad",
        "nocookieslogin": "{{SITENAME}} kasutab kasutajate tuvastamisel küpsiseid. Sinu brauseris on küpsised keelatud. Palun sea küpsised lubatuks ja proovi siis uuesti.",
        "nocookiesfornew": "Kasutajakonto jäi loomata, kuna me ei saanud selle allikat kindlaks teha.\nVeendu, et sul on küpsised lubatud, taaslaadi see lehekülg ja proovi uuesti.",
        "noname": "Sa ei sisestanud kasutajanime lubataval kujul.",
-       "loginsuccesstitle": "Sisselogimine õnnestus",
+       "loginsuccesstitle": "Sisse logitud",
        "loginsuccess": "Oled sisse loginud. Sinu kasutajanimi on \"$1\".",
        "nosuchuser": "Kasutajat \"$1\" pole.\nKasutajanimed on tõstutundlikud.\nKontrolli kirjapilti või [[Special:CreateAccount|loo uus konto]].",
        "nosuchusershort": "Kasutajat nimega \"$1\" pole.\nKontrolli kirjapilti.",
        "noemail": "Kasutaja $1 e-posti aadressi meil kahjuks pole.",
        "noemailcreate": "Pead sisestama korrektse e-posti aadressi",
        "passwordsent": "Uus parool on saadetud kasutaja $1 registreeritud e-postiaadressil.\nPärast parooli saamist logige palun sisse.",
-       "blocked-mailpassword": "Sinu IP-aadressi jaoks on toimetamine blokeeritud, seetõttu ei saa sa kasutada ka parooli meeldetuletamise funktsiooni.",
+       "blocked-mailpassword": "Sinu IP-aadressi jaoks on toimetamine blokeeritud. Et väärtarvitust ennetada, ei saa sellelt IP-aadressilt kasutada parooli meeldetuletamise funktsiooni.",
        "eauthentsent": "Määratud e-posti aadressile on saadetud kinnituse e-kiri.\nEnne kui su kontole ükskõik milline muu e-kiri saadetakse, pead e-kirjas olevat juhist järgides kinnitama, et konto on tõepoolest sinu.",
        "throttled-mailpassword": "Parooli lähtestamise e-kiri saadetud viimase {{PLURAL:$1|tunni|$1 tunni}} jooksul.\nVäärtarvitamise vältimiseks saadetakse {{PLURAL:$1|tunni|$1 tunni}} jooksul ainult üks lähtestamise e-kiri.",
        "mailerror": "Viga kirja saatmisel: $1",
        "newpassword": "Uus parool:",
        "retypenew": "Sisesta uus parool uuesti:",
        "resetpass_submit": "Sisesta parool ja logi sisse",
-       "changepassword-success": "Sinu parool on edukalt muudetud!\nSind logitakse nüüd sisse...",
+       "changepassword-success": "Sinu parool on muudetud!",
        "changepassword-throttled": "Oled hiljuti proovinud liiga palju kordi sisse logida.\nPalun oota $1, enne kui uuesti proovid.",
        "resetpass_forbidden": "Paroole ei saa muuta",
        "resetpass-no-info": "Pead olema sisselogitud, et sellele lehele pääseda.",
        "resetpass-submit-loggedin": "Muuda parool",
        "resetpass-submit-cancel": "Loobu",
-       "resetpass-wrong-oldpass": "Vigane ajutine või praegune salasõna.\nVõib-olla oled juba edukalt muudnud oma salasõna või taotlenud uut ajutist salasõna.",
+       "resetpass-wrong-oldpass": "Vigane ajutine või praegune salasõna.\nVõib-olla oled juba muutnud oma salasõna või taotlenud uut ajutist salasõna.",
        "resetpass-recycled": "Palun vali uus salasõna, mis erineb praegusest.",
        "resetpass-temp-emailed": "Logisid sisse e-posti teel saadud ajutise koodiga.\nEt sisselogimine lõpule viia, pead määrama siin uue parooli:",
        "resetpass-temp-password": "Ajutine parool:",
        "userpage-userdoesnotexist": "Kasutajakontot \"<nowiki>$1</nowiki>\" pole olemas.\nPalun mõtle järele, kas soovid seda lehte luua või muuta.",
        "userpage-userdoesnotexist-view": "Kasutajakonto \"$1\" pole registreeritud.",
        "blocked-notice-logextract": "See kasutaja on praegu blokeeritud.\nAllpool on toodud viimane blokeerimislogi sissekanne:",
-       "clearyourcache": "'''Märkus:''' Võimalik, et pärast salvestamist tuleb muudatuste nägemiseks veebilehitseja puhver tühjendada.\n* '''Firefox / Safari:''' Hoia all ''Shift''-klahvi ja klõpsa ''Laadi uuesti'' või vajuta kas ''Ctrl-F5'' või ''Ctrl-R'' (Macis ''⌘-R'').\n* '''Google Chrome:''' Vajuta ''Ctrl-Shift-R'' (Macis ''⌘-Shift-R'').\n* '''Internet Explorer:''' Hoia all ''Ctrl''-klahvi ja klõpsa ''Värskenda'' või vajuta ''Ctrl-F5''.\n* '''Opera:''' Tühjenda puhver asukohas ''Seaded → Eelistused''.",
+       "clearyourcache": "<strong>Märkus:</strong> Võimalik, et pärast salvestamist tuleb muudatuste nägemiseks veebilehitseja puhver tühjendada.\n* <strong>Firefox / Safari:</strong> Hoia all <em>Shift</em>-klahvi ja klõpsa <em>Laadi uuesti</em> või vajuta kas <em>Ctrl-F5</em> või <em>Ctrl-R</em> (Macis <em>⌘-R</em>).\n* <strong>Google Chrome:</strong> Vajuta <em>Ctrl-Shift-R</em> (Macis <em>⌘-Shift-R</em>).\n* <strong>Internet Explorer:</strong> Hoia all <em>Ctrl</em>-klahvi ja klõpsa <em>Värskenda</em> või vajuta <em>Ctrl-F5</em>.\n* <strong>Opera:</strong> Mine asukohta <em>Menüü → Seaded</em> (Macis <em>Opera → Eelistused</em>) ja seejärel <em>Privaatsus ja turvalisus → Tühjenda sirvimisandmed → Puhverdatud pildid ja failid</em>.",
        "usercssyoucanpreview": "'''Vihje:''' Enne salvestamist kasuta oma uue CSSi proovimiseks nuppu \"{{int:showpreview}}\".",
        "userjsyoucanpreview": "'''Vihje:''' Enne salvestamist kasuta oma uue JavaScripti proovimiseks nuppu \"{{int:showpreview}}\".",
        "usercsspreview": "'''Ära unusta, et seda versiooni sinu isiklikust stiililehest pole veel salvestatud!'''",
        "previewnote": "'''Ära unusta, et see on kõigest eelvaade!'''\nSinu muudatused pole veel salvestatud!",
        "continue-editing": "Mine redigeerimiskasti juurde",
        "previewconflict": "See eelvaade näitab, kuidas ülemises toimetuskastis olev tekst hakkab välja nägema, kui otsustate salvestada.",
-       "session_fail_preview": "'''Vabandust! Meil ei õnnestunud seansiandmete kaotuse tõttu sinu muudatust töödelda.'''\nPalun proovi uuesti.\nKui see ikka ei tööta, proovi [[Special:UserLogout|välja]] ja tagasi sisse logida.",
-       "session_fail_preview_html": "'''Vabandust! Meil ei õnnestunud seansiandmete kaotuse tõttu sinu muudatust töödelda.'''\n\n''Kuna {{GRAMMAR:inessive|{{SITENAME}}}} on toor-HTML lubatud, on eelvaade JavaScripti-rünnakute vastase ettevaatusabinõuna peidetud.''\n\n'''Kui see on õigustatud redigeerimiskatse, proovi palun uuesti.'''\nKui see ikka ei tööta, proovi [[Special:UserLogout|välja]] ja tagasi sisse logida.",
+       "session_fail_preview": "Vabandust! Meil ei õnnestunud seansiandmete kaotuse tõttu sinu muudatust töödelda.\n\nVõimalik, et oled välja loginud. <strong>Palun veendu, et oled endiselt sisse logitud ja proovi uuesti</strong>.\nKui see ei toimi, siis proovi [[Special:UserLogout|logida välja]] ja seejärel tagasi sisse ning kontrolli, kas brauser lubab sellest võrgukohast küpsiseid.",
+       "session_fail_preview_html": "Vabandust! Meil ei õnnestunud seansiandmete kaotuse tõttu sinu muudatust töödelda.\n\n<em>Kuna {{GRAMMAR:inessive|{{SITENAME}}}} on toor-HTML lubatud, on eelvaade JavaScripti-rünnakute vastase ettevaatusabinõuna peidetud.</em>\n\n<strong>Kui see on õigustatud redigeerimiskatse, proovi palun uuesti.</strong>\nKui see ikka ei tööta, proovi [[Special:UserLogout|välja]] ja tagasi sisse logida ning kontrolli, kas brauser lubab sellest võrgukohast küpsiseid.",
        "token_suffix_mismatch": "'''Muudatus lükati tagasi, kuna sinu klienttarkvara ei suuda õigesti kirjavahemärke kasutada.'''\nMuudatus lükati tagasi, et vältida lehekülje segiminekut.\nSee juhtub mõnikord siis, kui kasutatakse vigast veebipõhist anonüümsusserverit.",
        "edit_form_incomplete": "'''Redigeerimisvormi mõni osa ei jõudnud serverisse; kontrolli, kas sinu tehtud muudatused on alles, ja proovi uuesti.'''",
        "editing": "Muutmisel on \"$1\"",
        "revdelete-unsuppress": "Eemalda taastatud redaktsioonidelt piirangud",
        "revdelete-log": "Põhjus:",
        "revdelete-submit": "Rakenda valitud {{PLURAL:$1|redaktsiooni|redaktsioonide}} suhtes",
-       "revdelete-success": "Redaktsiooni nähtavus edukalt värskendatud.",
+       "revdelete-success": "Redaktsiooni nähtavus värskendatud.",
        "revdelete-failure": "'''Redaktsiooni nähtavust ei saanud värskendada:'''\n$1",
-       "logdelete-success": "'''Logi nähtavus edukalt muudetud.'''",
+       "logdelete-success": "Logi nähtavus muudetud.",
        "logdelete-failure": "'''Logi nähtavust ei saanud paika:'''\n$1",
        "revdel-restore": "muuda nähtavust",
        "pagehist": "lehekülje ajalugu",
        "userrights": "Kasutajaõiguste haldus",
        "userrights-lookup-user": "Kasutajarühma muutmine",
        "userrights-user-editname": "Sisesta kasutajanimi:",
-       "editusergroup": "Muuda kasutajarühmi",
+       "editusergroup": "Muuda {{GENDER:$1|kasutajarühmi}}",
        "editinguser": "Kasutaja '''[[User:$1|$1]]''' $2 õiguste muutmine",
        "userrights-editusergroup": "Kasutajarühmade muutmine",
-       "saveusergroups": "Salvesta kasutajarühmad",
+       "saveusergroups": "Salvesta {{GENDER:$1|kasutajarühmad}}",
        "userrights-groupsmember": "Kuulub rühmadesse:",
        "userrights-groupsmember-auto": "Kuulub vaikimisi rühmadesse:",
        "userrights-groups-help": "Sa võid muuta selle kasutaja kuuluvust eri kasutajarühmadesse.\n* Märgitud kast tähendab, et kasutaja kuulub sellesse rühma.\n* Märkimata kast tähendab, et kasutaja ei kuulu sellesse rühma.\n* Aga * kasutajarühma juures tähistab õigust, mida sa peale lisamist enam eemaldada ei saa, või siis ka vastupidi.",
        "userrights-changeable-col": "Rühmad, mida sa saad muuta",
        "userrights-unchangeable-col": "Rühmad, mida sa ei saa muuta",
        "userrights-conflict": "Kasutajaõiguste muutmise konflikt! Palun vaata oma muudatused üle ja kinnita need.",
-       "userrights-removed-self": "Võtsid edukalt endalt õigused. Seetõttu sellele leheküljele sa enam ligi ei pääse.",
+       "userrights-removed-self": "Võtsid endalt õigused. Seetõttu sellele leheküljele sa enam ligi ei pääse.",
        "group": "Rühm:",
        "group-user": "Kasutajad",
        "group-autoconfirmed": "Automaatselt kinnitatud kasutajad",
        "right-override-export-depth": "Eksportida lehekülgi, kaasates viidatud leheküljed kuni viienda tasemeni",
        "right-sendemail": "Saata teistele kasutajatele e-kirju",
        "right-passwordreset": "Vaadata parooli lähtestamise e-kirju",
-       "right-managechangetags": "Koostada [[Special:Tags|märgiseid]] ja kustutada neid andmebaasist",
+       "right-managechangetags": "Koostada ja (in)aktiveerida [[Special:Tags|märgiseid]]",
        "right-applychangetags": "Rakendada [[Special:Tags|märgiseid]] enda muudatuste suhtes",
        "right-changetags": "Lisada ja eemaldada käsitsi rakendatavaid [[Special:Tags|märgiseid]] üksikute redaktsioonide ja logisissekannete juures",
        "grant-group-page-interaction": "Interaktsioon lehekülgedega",
        "grant-sendemail": "Kasutajatele e-kirjade saatmine",
        "grant-uploadeditmovefile": "Failide üleslaadimine, asendamine ja teisaldamine",
        "grant-uploadfile": "Uute failide üleslaadimine",
+       "grant-basic": "Põhiõigused",
        "grant-viewdeleted": "Kustutatud failide ja lehekülgede vaatamine",
        "grant-viewmywatchlist": "Oma jälgimisloendi vaatamine",
        "newuserlogpage": "Konto loomise logi",
        "rightslogtext": "See on logi kasutajate õiguste muutuste kohta.",
        "action-read": "seda lehekülge lugeda",
        "action-edit": "seda lehekülge muuta",
-       "action-createpage": "lehekülgi luua",
-       "action-createtalk": "arutelulehekülgi luua",
+       "action-createpage": "seda lehekülge luua",
+       "action-createtalk": "seda arutelulehekülge luua",
        "action-createaccount": "seda kasutajakontot luua",
        "action-history": "vaadata selle lehekülje ajalugu",
        "action-minoredit": "seda muudatust pisimuudatuseks märkida",
        "action-viewmyprivateinfo": "oma eraandmeid vaadata",
        "action-editmyprivateinfo": "oma eraandmeid redigeerida",
        "action-editcontentmodel": "lehekülje sisumudelit muuta",
-       "action-managechangetags": "märgiseid koostada ege neid andmebaasist kustutada",
+       "action-managechangetags": "märgiseid koostada ega (in)aktiveerida",
        "action-applychangetags": "rakendada märgiseid oma muudatuste suhtes",
        "action-changetags": "käsitsi rakendatavaid märgiseid üksikute redaktsioonide ega logisissekannete juures lisada ega eemaldada",
        "nchanges": "$1 {{PLURAL:$1|muudatus|muudatust}}",
        "recentchangeslinked-page": "Lehekülje nimi:",
        "recentchangeslinked-to": "Näita hoopis muudatusi lehekülgedel, mis sellele lehele lingivad",
        "recentchanges-page-added-to-category": "kategooriasse lisatud \"[[:$1]]\"",
-       "recentchanges-page-added-to-category-bundled": "kategooriasse lisatud \"[[:$1]]\" ja veel [[Special:WhatLinksHere/$1|{{PLURAL:$2|üks lehekülg|$2 lehekülge}}]]",
+       "recentchanges-page-added-to-category-bundled": "kategooriasse lisatud \"[[:$1]]\", [[Special:WhatLinksHere/$1|seda lehekülge kasutatakse teisel leheküljel mallina]]",
        "recentchanges-page-removed-from-category": "kategooriast eemaldatud \"[[:$1]]\"",
-       "recentchanges-page-removed-from-category-bundled": "kategooriast eemaldatud \"[[:$1]]\" ja veel {{PLURAL:$2|üks lehekülg|$2 lehekülge}}",
+       "recentchanges-page-removed-from-category-bundled": "kategooriast eemaldatud \"[[:$1]]\", [[Special:WhatLinksHere/$1|seda lehekülge kasutatakse teisel leheküljel mallina]]",
        "autochange-username": "MediaWiki automaatne muudatus",
        "upload": "Faili üleslaadimine",
        "uploadbtn": "Laadi fail üles",
        "uploaded-script-svg": "Üleslaaditud SVG-failist leiti skriptitav element \"$1\".",
        "uploaded-hostile-svg": "Üleslaaditud SVG-faili laadielemendist leiti ebaturvaline CSS.",
        "uploaded-event-handler-on-svg": "Sündmuse halduse atribuutide <code>$1=\"$2\"</code> seadmine pole SVG-failis lubatud.",
-       "uploaded-href-unsafe-target-svg": "Üleslaaditud SVG-failist leiti href, mille sihtkoht <code>&lt;$1 $2=\"$3\"&gt;</code> on ebaturvaline.",
+       "uploaded-href-unsafe-target-svg": "Üleslaaditud SVG-failist leiti href, mis viitab ebaturvalistele andmetele: URI sihtkoht <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "Üleslaaditud SVG-failist leiti silt \"animate\", mis võib href-i muuta, kasutades from-atribuuti <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Sündmuse halduse atribuutide seadmine on keelatud, üleslaaditud SVG-failist leiti <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-href-svg": "Sildi \"set\" kasutamine, selleks et lisada emaelemendile href-atribuut, on keelatud.",
        "backend-fail-read": "Faili $1 ei saa lugeda.",
        "backend-fail-create": "Faili $1 ei saa kirjutada.",
        "backend-fail-maxsize": "Faili $1 ei saa kirjutada, sest see on {{PLURAL:$2|ühest baidist|$2 baidist}} suurem.",
-       "backend-fail-readonly": "Tagamälu \"$1\" on praegu kirjutuskaitstud. Põhjus: \"<em>$2</em>\"",
+       "backend-fail-readonly": "Tagamälu \"$1\" on praegu kirjutuskaitstud. Põhjus: <em>$2</em>",
        "backend-fail-synced": "Faili \"$1\" olek sisemälus on ühtimatu.",
        "backend-fail-connect": "Ühendus tagamäluga \"$1\" ebaõnnestus.",
        "backend-fail-internal": "Tagamälus \"$1\" esines tundmatu tõrge.",
        "uploadstash-summary": "See lehekülg pakub juurdepääsu failidele, mis on üles laaditud (või mida parasjagu üles laaditakse), kuid mis pole veel vikis avaldatud. Need failid on nähtavad üksnes kasutajale, kes need üles laadis.",
        "uploadstash-clear": "Kustuta failid algsest hoidlast",
        "uploadstash-nofiles": "Sul pole algses hoidlas faile.",
-       "uploadstash-badtoken": "Toiming ebaõnnestus; võib-olla redigeerimisloa aegumise tõttu. Proovi uuesti.",
+       "uploadstash-badtoken": "Toiming ebaõnnestus, võib-olla redigeerimismandaadi aegumise tõttu. Palun proovi uuesti.",
        "uploadstash-errclear": "Failide kustutamine ebaõnnestus.",
        "uploadstash-refresh": "Värskenda faililoendit",
        "invalid-chunk-offset": "Tüki vigane nihe",
        "pageswithprop-prophidden-long": "pika tekstiatribuudi väärtus peidetud ($1)",
        "pageswithprop-prophidden-binary": "kahendatribuudi väärtus peidetud ($1)",
        "doubleredirects": "Kahekordsed ümbersuunamised",
-       "doubleredirectstext": "See lehekülg loetleb leheküljed, mis on ümber suunatud teistele ümbersuunamislehekülgedel.\nIgal real on toodud esimene ja teine ümbersuunamislehekülg ning samuti lehekülg, kuhu teine ümbersuunamislehekülg on suunatud ja kuhu tavaliselt ka esimene ümbersuunamislehekülg tegelikult peaks suunama.\n<del>Läbikriipsutatud</del> kirjed on kohendatud.",
+       "doubleredirectstext": "See lehekülg loetleb leheküljed, mis on ümber suunatud teistele ümbersuunamislehekülgedele.\nIgal real on toodud esimene ja teine ümbersuunamislehekülg ning samuti lehekülg, kuhu teine ümbersuunamislehekülg on suunatud ja kuhu tavaliselt ka esimene ümbersuunamislehekülg tegelikult peaks suunama.\n<del>Läbikriipsutatud</del> kirjed on kohendatud.",
        "double-redirect-fixed-move": "[[$1]] on teisaldatud.\nLehekülg uuendati automaatselt ja see suunab nüüd leheküljele [[$2]].",
        "double-redirect-fixed-maintenance": "Hooldustöö käigus parandati automaatselt kahekordne suunamine leheküljelt [[$1]] leheküljele [[$2]].",
        "double-redirect-fixer": "Ümbersuunamiste parandaja",
        "apihelp-no-such-module": "Moodulit \"$1\" ei leitud.",
        "apisandbox": "API liivakast",
        "apisandbox-api-disabled": "API on selles võrgukohas keelatud.",
-       "apisandbox-intro": "Kasuta seda lehekülge '''MediaWiki API''' katsetamiseks.\nÜksikasjad API kasutamise kohta leiad [https://www.mediawiki.org/wiki/API:Main_page API dokumentatsioonist]. Näide: [https://www.mediawiki.org/wiki/API#A_simple_example esilehe sisu hankimine]. Vali toiming, et näha veel näiteid.\n\nPane tähele, et kuigi siin on liivakast, võivad siin leheküljel tehtud toimingud vikit muuta.",
+       "apisandbox-intro": "Kasuta seda lehekülge <strong>MediaWiki API</strong> katsetamiseks.\nÜksikasjad API kasutamise kohta leiad [[mw:API:Main page|API dokumentatsioonist]]. Näide: [https://www.mediawiki.org/wiki/API#A_simple_example esilehe sisu hankimine]. Vali toiming, et näha veel näiteid.\n\nPane tähele, et kuigi siin on liivakast, võivad siin leheküljel tehtud toimingud vikit muuta.",
        "apisandbox-submit": "Tee päring",
        "apisandbox-reset": "Puhasta",
-       "apisandbox-examples": "Näide",
-       "apisandbox-results": "Tulemus",
+       "apisandbox-examples": "Näited",
+       "apisandbox-results": "Tulemused",
        "apisandbox-request-url-label": "Päringu URL:",
-       "apisandbox-request-time": "Päringuaeg: $1",
+       "apisandbox-request-time": "Päringuaeg: {{PLURAL:$1|$1 ms}}",
        "booksources": "Raamatuotsimine",
        "booksources-search-legend": "Raamatuotsimine",
        "booksources-search": "Otsi",
        "log-title-wildcard": "Selle tekstiga algavad pealkirjad",
        "showhideselectedlogentries": "Muuda valitud logisissekannete nähtavust",
        "log-edit-tags": "Muuda valitud logisissekannete märgiseid",
+       "checkbox-select": "Vali: $1",
+       "checkbox-all": "kõik",
+       "checkbox-none": "mitte ühtegi",
+       "checkbox-invert": "pööra",
        "allpages": "Kõik leheküljed",
        "nextpage": "Järgmine lehekülg ($1)",
        "prevpage": "Eelmine lehekülg ($1)",
        "listgrouprights-namespaceprotection-header": "Nimeruumipiirangud",
        "listgrouprights-namespaceprotection-namespace": "Nimeruum",
        "listgrouprights-namespaceprotection-restrictedto": "Redigeerimiseks vajalikud õigused",
-       "listgrants-summary": "See on OAuthi-volituste ja neile vastavate kasutajaõiguste loend. Kasutaja saab volitada rakenduse tarvituse enda nimel, aga vaid kasutaja valitud volituste piires. Rakenduse abil ei saa kasutaja nimel siiski kasutada õigusi, mida kasutajal pole.\nÜksikute õiguste kohta võib leiduda [[{{MediaWiki:Listgrouprights-helppage}}|lisateavet]].",
-       "listgrants-rights": "Volitus",
+       "listgrants": "Volitused",
+       "listgrants-summary": "See on volituste ja neile vastavate kasutajaõiguste loend. Kasutaja saab volitada rakenduse tarvituse enda nimel, aga vaid kasutaja valitud volituste piires. Rakenduse abil ei saa kasutaja nimel siiski kasutada õigusi, mida kasutajal pole.\nÜksikute õiguste kohta võib leiduda [[{{MediaWiki:Listgrouprights-helppage}}|lisateavet]].",
+       "listgrants-grant": "Volitus",
+       "listgrants-rights": "Õigused",
        "trackingcategories": "Süsteemikategooriad",
        "trackingcategories-summary": "Siin leheküljel on loetletud süsteemikategooriad, millesse MediaWiki tarkvara ise lehekülgi arvab. Nende kategooriate nimesid saab muuta, kui vahetada {{ns:8}}-nimeruumis vastavaid süsteemisõnumeid.",
        "trackingcategories-msg": "Süsteemikategooria",
        "delete-toobig": "See lehekülg on pika redigeerimisajalooga – üle {{PLURAL:$1|ühe muudatuse|$1 muudatuse}}.\nSelle kustutamine on keelatud, et ära hoida ekslikku {{GRAMMAR:genitive|{{SITENAME}}}} töö häirimist.",
        "delete-warning-toobig": "See lehekülg on pika redigeerimislooga – üle {{PLURAL:$1|ühe muudatuse|$1 muudatuse}}.\nEttevaatust, selle kustutamine võib esile kutsuda häireid {{GRAMMAR:genitive|{{SITENAME}}}} andmebaasi töös.",
        "deleteprotected": "Seda lehekülge ei saa kustutada, sest see on kaitstud.",
-       "deleting-backlinks-warning": "'''Hoiatus:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Teised leheküljed]] viitavad leheküljele, mida oled kustutamas, või see lehekülg on kasutuses mallina.",
+       "deleting-backlinks-warning": "<strong>Hoiatus:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Teised leheküljed]] viitavad leheküljele, mida oled kustutamas, või see lehekülg on kasutuses mallina.",
        "rollback": "Tühista muudatused",
        "rollbacklink": "tühista",
        "rollbacklinkcount": "tühista {{PLURAL:$1|üks muudatus|$1 muudatust}}",
        "protect-summary-cascade": "kaskaad",
        "protect-expiring": "aegumistähtaeg $1 (UTC)",
        "protect-expiring-local": "aegumistähtaeg $1",
-       "protect-expiry-indefinite": "määramatu",
+       "protect-expiry-indefinite": "tähtajatu",
        "protect-cascade": "Kaitse lehekülgi, mis on lülitatud käesoleva lehekülje koosseisu (kaskaadkaitse)",
        "protect-cantedit": "Sa ei saa lehekülje kaitsetaset muuta, sest sul puudub lehekülje redigeerimise õigus.",
        "protect-othertime": "Muu aeg:",
        "unblock": "Kasutaja blokeeringu eemaldamine",
        "blockip": "Blokeeri {{GENDER:$1|kasutaja}}",
        "blockip-legend": "Kasutaja blokeerimine",
-       "blockiptext": "See vorm on kindla IP-aadressi või kasutajanime kirjutamisõiguste blokeerimiseks.\nSeda tohib teha ainult vandalismi vältimiseks ja kooskõlas [[{{MediaWiki:Policy-url}}|{{GRAMMAR:genitive|{{SITENAME}}}} sisekorraga]].\nTäida ka põhjuse väli, näiteks viidates lehekülgedele, mis rikuti.",
+       "blockiptext": "See vorm on kindla IP-aadressi või kasutajanime kirjutamisõiguste blokeerimiseks.\nSeda tohib teha ainult vandalismi vältimiseks ja kooskõlas [[{{MediaWiki:Policy-url}}|{{GRAMMAR:genitive|{{SITENAME}}}} sisekorraga]].\nTäida ka põhjuse väli, näiteks viidates lehekülgedele, mis rikuti.\nIP-aadresside vahemikke saad blokeerida [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]-süntaksi abil; suurim lubatud vahemik on IPv4 jaoks /$1 ja IPv6 jaoks /$2.",
        "ipaddressorusername": "IP-aadress või kasutajanimi:",
        "ipbexpiry": "Kehtivus:",
        "ipbreason": "Põhjus:",
        "lockedbyandtime": "(lukustas $1; $2, kell $3)",
        "move-page": "Lehekülje \"$1\" teisaldamine",
        "move-page-legend": "Lehekülje teisaldamine",
-       "movepagetext": "Allolevat vormi kasutades saad lehekülje ümber nimetada. Lehekülje ajalugu tõstetakse uue pealkirja alla automaatselt.\nPraeguse pealkirjaga leheküljest saab ümbersuunamislehekülg uuele leheküljele.\nSaad senisele pealkirjale viitavad ümbersuunamised automaatselt parandada.\nKui sa seda ei tee, kontrolli, et teisaldamise tõttu ei jää maha [[Special:DoubleRedirects|kahekordseid]] ega [[Special:BrokenRedirects|katkiseid ümbersuunamisi]].\nSinu kohus on hoolitseda selle eest, et kõik jääks toimima, nagu ette nähtud.\n\nPane tähele, et lehekülge '''ei teisaldata''' juhul, kui uue pealkirjaga lehekülg on juba olemas. Erandiks on juhud, kui viimane on redigeerimisajaloota ümbersuunamislehekülg.\nSee tähendab, et kogemata ei saa üle kirjutada juba olemasolevat lehekülge, kuid saab ebaõnnestunud ümbernimetamise tagasi pöörata.\n\n'''Hoiatus!'''\nTegu võib olla väga loetava lehekülje jaoks tõsise ja ootamatu muudatusega;\nenne jätkamist teadvusta palun tagajärgi.",
-       "movepagetext-noredirectfixer": "Allolevat vormi kasutades saad lehekülje ümber nimetada. Lehekülje ajalugu tõstetakse uue pealkirja alla automaatselt.\nPraeguse pealkirjaga leheküljest saab ümbersuunamislehekülg uuele leheküljele.\nKontrolli, et teisaldamise tõttu ei jää maha [[Special:DoubleRedirects|kahekordseid]] ega [[Special:BrokenRedirects|katkiseid ümbersuunamisi]].\nSinu kohus on hoolitseda selle eest, et kõik jääks toimima, nagu ette nähtud.\n\nPane tähele, et lehekülge '''ei teisaldata''' juhul, kui uue pealkirjaga lehekülg on juba olemas. Erandiks on juhud, kui olemasolev lehekülg on tühi või redigeerimisajaloota ümbersuunamislehekülg.\nSee tähendab, et kogemata ei saa üle kirjutada juba olemasolevat lehekülge, kuid saab ebaõnnestunud ümbernimetamise tagasi pöörata.\n\n'''Hoiatus!'''\nTegu võib olla väga loetava lehekülje jaoks tõsise ja ootamatu muudatusega;\nenne jätkamist teadvusta palun tagajärgi.",
+       "movepagetext": "Allolevat vormi kasutades saad lehekülje ümber nimetada. Lehekülje ajalugu tõstetakse uue pealkirja alla automaatselt.\nPraeguse pealkirjaga leheküljest saab ümbersuunamislehekülg uuele leheküljele.\nSaad senisele pealkirjale viitavad ümbersuunamised automaatselt parandada.\nKui sa seda ei tee, kontrolli, et teisaldamise tõttu ei jää maha [[Special:DoubleRedirects|kahekordseid]] ega [[Special:BrokenRedirects|katkiseid ümbersuunamisi]].\nSinu kohus on hoolitseda selle eest, et kõik jääks toimima, nagu ette nähtud.\n\nPane tähele, et lehekülge <strong>ei teisaldata</strong> juhul, kui uue pealkirjaga lehekülg on juba olemas. Erandiks on juhud, kui viimane on redigeerimisajaloota ümbersuunamislehekülg.\nSee tähendab, et kogemata ei saa üle kirjutada juba olemasolevat lehekülge, kuid saab ebaõnnestunud ümbernimetamise tagasi pöörata.\n\n<strong>Märkus:</strong>\nTegu võib olla väga loetava lehekülje jaoks tõsise ja ootamatu muudatusega;\nenne jätkamist teadvusta palun tagajärgi.",
+       "movepagetext-noredirectfixer": "Allolevat vormi kasutades saad lehekülje ümber nimetada. Lehekülje ajalugu tõstetakse uue pealkirja alla automaatselt.\nPraeguse pealkirjaga leheküljest saab ümbersuunamislehekülg uuele leheküljele.\nKontrolli, et teisaldamise tõttu ei jää maha [[Special:DoubleRedirects|kahekordseid]] ega [[Special:BrokenRedirects|katkiseid ümbersuunamisi]].\nSinu kohus on hoolitseda selle eest, et kõik jääks toimima, nagu ette nähtud.\n\nPane tähele, et lehekülge <strong>ei teisaldata</strong> juhul, kui uue pealkirjaga lehekülg on juba olemas. Erandiks on juhud, kui olemasolev lehekülg on tühi või redigeerimisajaloota ümbersuunamislehekülg.\nSee tähendab, et kogemata ei saa üle kirjutada juba olemasolevat lehekülge, kuid saab ebaõnnestunud ümbernimetamise tagasi pöörata.\n\n<strong>Note:</strong>\nTegu võib olla väga loetava lehekülje jaoks tõsise ja ootamatu muudatusega;\nenne jätkamist teadvusta palun tagajärgi.",
        "movepagetalktext": "Kui märgid selle ruudu, teisaldatakse arutelulehekülg automaatselt uue pealkirja alla. Seda välja arvatud juhul, kui uue pealkirja all on juba arutelulehekülg, mis pole tühi.\n\nSel juhul saad lehekülje soovi korral käsitsi teisaldada või liita.",
        "moveuserpage-warning": "'''Hoiatus:''' Oled teisaldamas kasutajalehekülge. Pane tähele, et teisaldatakse ainult lehekülg ja kasutajat '''ei''' nimetata ümber.",
        "movecategorypage-warning": "<strong>Hoiatus:</strong> Oled teisaldamas kategoorialehekülge. Pane palun tähele, et teisaldatakse vaid see lehekülg ja ühtegi vanas kategoorias sisalduvat lehekülge <em>ei</em> kategoriseerita ümber uude kategooriasse.",
        "movenosubpage": "Sellel leheküljel pole alamlehekülgi.",
        "movereason": "Põhjus:",
        "revertmove": "taasta",
-       "delete_and_move_text": "== Vajalik kustutamine ==\nSihtlehekülg \"[[:$1]]\" on juba olemas.\nKas kustutad selle, et luua võimalus teisaldamiseks?",
+       "delete_and_move_text": "Sihtlehekülg \"[[:$1]]\" on juba olemas.\nKas kustutad selle, et luua võimalus teisaldamiseks?",
        "delete_and_move_confirm": "Jah, kustuta lehekülg",
        "delete_and_move_reason": "Kustutatud, et tõsta asemele lehekülg \"[[$1]]\"",
        "selfmove": "Algne nimi ja uus nimi on samad.",
        "move-leave-redirect": "Jäta maha ümbersuunamisleht",
        "protectedpagemovewarning": "'''Hoiatus:''' See lehekülg on nii lukustatud, et ainult administraatori õigustega kasutajad saavad seda teisaldada.\nAllpool on toodud uusim logisissekanne:",
        "semiprotectedpagemovewarning": "'''Pane tähele:''' See lehekülg on lukustatud, nii et ainult registreeritud kasutajad saavad seda teisaldada.\nAllpool on toodud uusim logisissekanne:",
-       "move-over-sharedrepo": "== Fail on olemas ==\n[[:$1]] on olemas jagatud failivaramus. Faili teisaldamisel selle nime alla varjatakse jagatud failivarmus olev samanimeline fail.",
+       "move-over-sharedrepo": "[[:$1]] on olemas jagatud failivaramus. Faili teisaldamisel selle nime alla varjatakse jagatud failivarmus olev samanimeline fail.",
        "file-exists-sharedrepo": "Valitud failinimi on juba kasutusel jagatud failivaramus.\nPalun kasuta mõnda teist nime.",
        "export": "Lehekülgede eksport",
        "exporttext": "Saad eksportida kindla leheküljel või lehekülgede kogumi teksti ja redigeerimisloo XML-kujule viiduna.\nSeda saab teise vikisse importida, kasutades selleks MediaWiki [[Special:Import|impordi lehekülge]].\n\nEt eksportida lehekülgi, sisesta nende pealkirjad allolevasse tekstikasti, iga pealkiri ise reale ja vali, kas soovid viimast redaktsiooni ja kõiki vanemaid redaktsioone ühes redigeerimislooga või viimast redaktsiooni ühes andmetega viimase redigeerimise kohta.\n\nViimasel juhul saab kasutada ka linki, näiteks lehekülje \"[[{{MediaWiki:Mainpage}}]]\" jaoks [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]].",
        "import-nonewrevisions": "Ühtegi redaktsiooni ei imporditud (kõik on juba olemas või tõrgete tõttu vahele jäetud).",
        "xml-error-string": "$1 real $2, tulbas $3 (bait $4): $5",
        "import-upload": "Laadi üles XML-andmed",
-       "import-token-mismatch": "Seansiandmed läksid kaduma.\nPalun ürita uuesti.",
+       "import-token-mismatch": "Seansiandmed läksid kaduma.\n\nVõimalik, et oled välja loginud. <strong>Palun veendu, et oled endiselt sisse logitud ja proovi uuesti</strong>.\nKui see ei toimi, siis proovi [[Special:UserLogout|logida välja]] ja tagasi sisse ning kontrolli, kas brauser lubab sellest võrgukohast küpsiseid.",
        "import-invalid-interwiki": "Määratud vikist ei saa importida.",
        "import-error-edit": "Lehekülge \"$1\" ei imporditud, sest sul pole õigust seda muuta.",
        "import-error-create": "Lehekülge \"$1\" ei imporditud, sest sul pole õigust seda luua.",
        "tooltip-t-recentchangeslinked": "Viimased muudatused lehekülgedel, millele on siit viidatud",
        "tooltip-feed-rss": "Selle lehekülje RSS-voog",
        "tooltip-feed-atom": "Selle lehekülje Atom-voog",
-       "tooltip-t-contributions": "Kuva selle kasutaja kaastöö",
-       "tooltip-t-emailuser": "Saada sellele kasutajale e-kiri",
+       "tooltip-t-contributions": "Kuva {{GENDER:$1|selle kasutaja}} kaastöö",
+       "tooltip-t-emailuser": "Saada {{GENDER:$1|sellele kasutajale}} e-kiri",
        "tooltip-t-info": "Lisateave selle lehekülje kohta",
        "tooltip-t-upload": "Laadi faile üles",
        "tooltip-t-specialpages": "Erilehekülgede loend",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|lehekülg|lehekülge}}",
        "file-info": "faili suurus: $1, MIME tüüp: $2",
        "file-info-size": "$1 × $2 pikslit, faili suurus: $3, MIME tüüp: $4",
-       "file-info-size-pages": "$1 × $2 pikslit, faili suurus: $3 , MIME tüüp: $4, $5 {{PLURAL:$5|lehekülg|lehekülge}}",
+       "file-info-size-pages": "$1 × $2 pikslit, faili suurus: $3, MIME tüüp: $4, $5 {{PLURAL:$5|lehekülg|lehekülge}}",
        "file-nohires": "Sellest suuremat pilti pole.",
        "svg-long-desc": "SVG-fail, algsuurus $1 × $2 pikslit, faili suurus: $3",
        "svg-long-desc-animated": "Animeeritud SVG-fail,  algsuurus $1 × $2 pikslit, faili suurus: $3",
        "watchlistedit-raw-done": "Sinu jälgimisloend on uuendatud.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 lehekülg|$1 lehekülge}} lisatud:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 pealkiri|$1 pealkirja}} eemaldati:",
-       "watchlistedit-clear-title": "Tühjendatud jälgimisloend",
+       "watchlistedit-clear-title": "Jälgimisloendi tühjendamine",
        "watchlistedit-clear-legend": "Jälgimisloendi tühjendamine",
        "watchlistedit-clear-explain": "Sinu jälgimisloendist eemaldatakse kõik pealkirjad.",
        "watchlistedit-clear-titles": "Pealkirjad:",
        "version-libraries-license": "Litsents",
        "version-libraries-description": "Kirjeldus",
        "version-libraries-authors": "Autorid",
-       "redirect": "Ümbersuunamine faili, kasutaja, lehekülje või redaktsiooni identifikaatori järgi",
-       "redirect-summary": "See erilehekülg suunab ümber faili (toodud failinimi), lehekülje (toodud redaktsiooni või lehekülje identifikaator) või kasutajalehekülje (toodud numbriline kasutaja identfikaator) juurde. Kasutamine: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]] või [[{{#Special:Redirect}}/user/101]].",
+       "redirect": "Ümbersuunamine faili, kasutaja, lehekülje, redaktsiooni või logiidentifikaatori järgi",
+       "redirect-summary": "See erilehekülg suunab ümber faili (toodud failinimi), lehekülje (toodud redaktsiooni või lehekülje identifikaator), kasutajalehekülje (toodud numbriline kasutaja identfikaator) või logisissekande (toodud logiidentifikaator) juurde. Kasutamine: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] või [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Mine",
        "redirect-lookup": "Leia:",
        "redirect-value": "Väärtus:",
        "tags-delete-not-allowed": "Tarkvaralisas määratletud märgiseid ei saa kustutada, kui märgis on tarkvaralisas eraldi lubatud.",
        "tags-delete-not-found": "Märgist \"$1\" pole.",
        "tags-delete-too-many-uses": "Märgist \"$1\" on rakendatud rohkem kui {{PLURAL:$2|ühe|$2}} redaktsiooni juures, mistõttu ei saa seda kustutada.",
-       "tags-delete-warnings-after-delete": "Märgis \"$1\" on edukalt kustutatud, kuid väljastati {{PLURAL:$2|järgmine hoiatus|järgmised hoiatused}}:",
+       "tags-delete-warnings-after-delete": "Märgis \"$1\" on kustutatud, kuid väljastati {{PLURAL:$2|järgmine hoiatus|järgmised hoiatused}}:",
        "tags-activate-title": "Märgise lubamine",
        "tags-activate-question": "Siinkohal lubad märgise \"$1\".",
        "tags-activate-reason": "Põhjus:",
        "tags-edit-revision-legend": "Märgiste lisamine või eemaldamine {{PLURAL:$1|selle|kõigi $1}} redaktsiooni juures",
        "tags-edit-logentry-legend": "Märgiste lisamine või eemaldamine {{PLURAL:$1|selle|kõigi $1}} logisissekande juures",
        "tags-edit-existing-tags": "Senised märgised:",
-       "tags-edit-existing-tags-none": "''puuduvad''",
+       "tags-edit-existing-tags-none": "<em>puuduvad</em>",
        "tags-edit-new-tags": "Uued märgised:",
        "tags-edit-add": "Lisa need märgised:",
        "tags-edit-remove": "Eemalda need märgised:",
        "tags-edit-reason": "Põhjus:",
        "tags-edit-revision-submit": "Rakenda {{PLURAL:$1|selle|$1}} redaktsiooni suhtes",
        "tags-edit-logentry-submit": "Rakenda {{PLURAL:$1|selle|$1}} logisissekande suhtes",
-       "tags-edit-success": "Muudatused on edukalt rakendatud.",
+       "tags-edit-success": "Muudatused on rakendatud.",
        "tags-edit-failure": "Muudatusi ei õnnestunud rakendada:\n$1",
        "tags-edit-nooldid-title": "Vigane sihtredaktsioon",
        "tags-edit-nooldid-text": "Selle toimingu jaoks pole määratud ühtegi sihtredaktsiooni või määratud redaktsiooni pole olemas.",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|kaitses}} lehekülje $3 $4 [kaskaadkaitse]",
        "logentry-protect-modify": "$1 {{GENDER:$2|muutis}} lehekülje $3 kaitsetaset $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|muutis}} lehekülje $3 kaitsetaset $4 [kaskaadkaitse]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|muutis}} kasutaja $3 rühmaliikmesust; enne oli $4, nüüd on $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|muutis}} kasutaja {{GENDER:$6|$3}} rühmaliikmesust; enne oli $4, nüüd on $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|muutis}} kasutaja $3 rühmaliikmesust",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|viidi}} automaatselt üle teise rühma; enne oli $4, nüüd on $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|laadis üles}} faili $3",
        "expand_templates_generate_xml": "Näita XML-liigenduspuud",
        "expand_templates_generate_rawhtml": "Näita toor-HTMLi",
        "expand_templates_preview": "Eelvaade",
-       "expand_templates_preview_fail_html": "<em>Kuna {{GRAMMAR:inessive|{{SITENAME}}}} on toor-HTML lubatud ja osa seansiandmeid läks kaotsi, siis on JavaScripti põhiste rünnakute vastase abinõuna eelvaade peidetud.</em>\n\n<strong>Kui see eelvaatekatse on õigustatud, proovi palun uuesti.</strong>\nKui see ikka ei tööta, proovi [[Special:UserLogout|logida välja]] ja tagasi sisse.",
+       "expand_templates_preview_fail_html": "<em>Kuna {{GRAMMAR:inessive|{{SITENAME}}}} on toor-HTML lubatud ja osa seansiandmeid läks kaotsi, siis on JavaScripti põhiste rünnakute vastase abinõuna eelvaade peidetud.</em>\n\n<strong>Kui see eelvaatekatse on õigustatud, proovi palun uuesti.</strong>\nKui see ikka ei tööta, proovi [[Special:UserLogout|logida välja]] ja tagasi sisse ning kontrolli, kas brauser lubab sellest võrgukohast küpsiseid.",
        "expand_templates_preview_fail_html_anon": "<em>Kuna {{GRAMMAR:inessive|{{SITENAME}}}} on toor-HTML lubatud ja sa pole sisse logitud, siis on JavaScripti põhiste rünnakute vastase abinõuna eelvaade peidetud.</em>\n\n<strong>Kui see eelvaatekatse on õigustatud, [[Special:UserLogin|logi]] palun sisse ja proovi uuesti.</strong>",
        "pagelanguage": "Lehekülje keele valik",
        "pagelang-name": "Lehekülg",
        "mediastatistics": "Meediafailide arvandmestik",
        "mediastatistics-summary": "Arvandmed üles laaditud failitüüpide kohta. See käib ainult failide viimaste versioonide kohta. Vanu ja kustutatud versioone pole arvesse võetud.",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 bait|$1 baiti}} ($2; $3%)",
-       "mediastatistics-bytespertype": "Failide kogusuurus selles alaosas: $1 baiti.",
-       "mediastatistics-allbytes": "Kõigi failide kogusuurus: $1 baiti.",
+       "mediastatistics-bytespertype": "Failide kogusuurus selles alaosas: $1 {{PLURAL:$1|bait|baiti}} ($2; $3%).",
+       "mediastatistics-allbytes": "Kõigi failide kogusuurus: $1 {{PLURAL:$1|bait|baiti}} ($2).",
        "mediastatistics-table-mimetype": "MIME tüüp",
        "mediastatistics-table-extensions": "Võimalikud laiendid",
        "mediastatistics-table-count": "Failide arv",
        "mw-widgets-dateinput-placeholder-month": "AAAA-KK",
        "mw-widgets-titleinput-description-new-page": "lehekülge pole veel",
        "mw-widgets-titleinput-description-redirect": "ümbersuunamine leheküljele \"$1\"",
-       "api-error-blacklisted": "Palun vali muu pealkiri, mis on kirjeldav.",
        "randomrootpage": "Juhuslik juurlehekülg"
 }
index f3ecd93..9f4442b 100644 (file)
        "minoredit": "Aldaketa hau txikia da",
        "watchthis": "Orrialde hau jarraitu",
        "savearticle": "Gorde orria",
+       "publishpage": "Orrialdea argitaratu",
+       "publishchanges": "Aldaketak argitaratu",
        "preview": "Aurrebista erakutsi",
        "showpreview": "Aurrebista erakutsi",
        "showdiff": "Aldaketak erakutsi",
        "sp-contributions-search": "Ekarpenentzako bilaketa",
        "sp-contributions-username": "IP helbidea edo erabiltzaile izena:",
        "sp-contributions-toponly": "Azken aldaketak direnak soilik erakutsi",
+       "sp-contributions-newonly": "Orrialde sorkuntza direnak soilik erakutsi",
+       "sp-contributions-hideminor": "Aldaketa txikiak ezkutatu",
        "sp-contributions-submit": "Bilatu",
        "whatlinkshere": "Honanzko lotura duten orriak",
        "whatlinkshere-title": "$1(e)ra lotura duten orriak",
        "mw-widgets-dateinput-no-date": "Ez duzu datarik aukeratu",
        "mw-widgets-titleinput-description-new-page": "orri hori oraindik ez da existitzen",
        "mw-widgets-titleinput-description-redirect": "$1ra birzuzendu",
-       "api-error-blacklisted": "Aukera ezazu, mesedez, izenburu ezberdin eta deskriptiboago bat.",
        "sessionprovider-generic": "$1 sesio"
 }
index c76b7b7..8c8cee9 100644 (file)
        "content-model-css": "سی‌اس‌اس",
        "content-json-empty-object": "ابجکت خالی",
        "content-json-empty-array": "آرایهٔ خالی",
+       "deprecated-self-close-category": "صفحه از برچسب اچ‌تی‌ام‌ال self-closed غیرمجاز استفاده می‌کند",
+       "deprecated-self-close-category-desc": "صفحه دارای برچسب اچ‌تی‌ام‌ال self-closed است مانند <code>&lt;b/></code> یا <code>&lt;span/></code>. عملکرد این برچسب‌ها در اچ‌تی‌ام‌ال۵ تغییر می‌کند در نتیجه استفاده از آنها در ویکی‌متن منسوخ و بی‌اثر است.",
        "duplicate-args-warning": "<strong>هشدار:</strong> [[:$1]] [[:$2]] را با بیش از یک مقدار برای پارامتر «$3» صدا می‌زند. فقط آخرین مقدار داده شده استفاده خواهد شد.",
        "duplicate-args-category": "صفحه‌های دارای آرگومان تکراری در فراخوانی الگو",
        "duplicate-args-category-desc": "صفحاتی که دارای آرگومان تکراری هستند مانند، <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> یا <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-no-date": "هیچ داده‌ای انتخاب نشده",
        "mw-widgets-titleinput-description-new-page": "این صفحه هنوز وجود ندارد",
        "mw-widgets-titleinput-description-redirect": "تغییر مسیر به $1",
-       "api-error-blacklisted": "لطفاً یک عنوان توصیفی متفاوت انتخاب کنید.",
        "sessionmanager-tie": "نمی‌توان چندین نوع درخواست هویت‌سنجی را ترکیب کرد: $1.",
        "sessionprovider-generic": "$1 فصل",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "فصل‌های کوکی‌محور",
        "log-action-filter-newusers": "نوع ایجاد حساب",
        "log-action-filter-patrol": "نوع گشت:",
        "log-action-filter-protect": "نوع محافظت",
-       "log-action-filter-rights": "روش تغییر صحیح",
-       "log-action-filter-suppress": "روش سرکوب",
+       "log-action-filter-rights": "روش تغییر صحیح:",
+       "log-action-filter-suppress": "روش سرکوب:",
        "log-action-filter-upload": "نوع بارگذاری",
        "log-action-filter-all": "همه",
        "log-action-filter-block-block": "بستن",
index f7f277d..07869da 100644 (file)
        "mw-widgets-dateinput-placeholder-month": "VVVV-KK",
        "mw-widgets-titleinput-description-new-page": "sivua ei ole olemassa vielä",
        "mw-widgets-titleinput-description-redirect": "ohjaus kohteeseen $1",
-       "api-error-blacklisted": "Valitse toinen, kuvaava nimi.",
        "sessionmanager-tie": "!!FYZZ!!Cannot combine multiple request authentication types: $1.",
        "sessionprovider-generic": "$1 istuntoa",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "istuntoja, joissa on evästeet käytössä",
index fa53be2..4d7507b 100644 (file)
        "viewhelppage": "Voir la page d'aide",
        "categorypage": "Voir la page de catégorie",
        "viewtalkpage": "Voir la page de discussion",
-       "otherlanguages": "Dans d'autres langues",
+       "otherlanguages": "Dans dautres langues",
        "redirectedfrom": "(Redirigé depuis $1)",
        "redirectpagesub": "Page de redirection",
        "redirectto": "Rediriger vers :",
        "jumpto": "Aller à :",
        "jumptonavigation": "navigation",
        "jumptosearch": "rechercher",
-       "view-pool-error": "Désolé, les serveurs sont surchargés en ce moment.\nTrop d’utilisateurs cherchent à consulter cette page.\nVeuillez attendre un peu avant de réessayer d’accéder à celle-ci.\n\n$1",
+       "view-pool-error": "Désolé, les serveurs sont surchargés en ce moment.\nTrop d’utilisateurs cherchent à consulter cette page.\nVeuillez attendre un peu avant d’essayer à nouveau d’accéder à celle-ci.\n\n$1",
        "generic-pool-error": "Désolé, les serveurs sont surchargés en ce moment.\nTrop d’utilisateurs cherchent à consulter cette ressource.\nVeuillez attendre un peu avant de tenter à nouveau l’accès à celle-ci.",
        "pool-timeout": "Délai d’attente du verrou dépassé",
        "pool-queuefull": "La file des processus est pleine",
        "currentevents-url": "Project:Actualités",
        "disclaimers": "Avertissements",
        "disclaimerpage": "Project:Avertissements généraux",
-       "edithelp": "Aide",
+       "edithelp": "Aide pour l'édition",
        "helppage-top-gethelp": "Aide",
        "mainpage": "Accueil",
        "mainpage-description": "Accueil",
        "viewdeleted": "Voir $1 ?",
        "restorelink": "{{PLURAL:$1|une modification effacée|$1 modifications effacées}}",
        "feedlinks": "Flux :",
-       "feed-invalid": "Type de flux invalide pour abonnement.",
+       "feed-invalid": "Type de flux d’abonnement non valide.",
        "feed-unavailable": "Les flux de syndication ne sont pas disponibles",
        "site-rss-feed": "Flux RSS de $1",
        "site-atom-feed": "Flux Atom de $1",
        "viewyourtext": "Vous pouvez voir et copier le contenu de <strong>vos modifications</strong> à cette page.",
        "protectedinterface": "Cette page fournit du texte d’interface pour le logiciel sur ce wiki et est protégée pour éviter les abus.\nPour ajouter ou modifier des traductions sur tous les wikis, veuillez utiliser [https://translatewiki.net/ translatewiki.net], le projet de localisation de MediaWiki.",
        "editinginterface": "<strong>Attention :</strong> vous êtes en train de modifier une page utilisée pour créer le texte de l’interface du logiciel.\nLes changements sur cette page se répercuteront sur l’apparence de l’interface utilisateur pour les autres utilisateurs de ce wiki.",
-       "translateinterface": "Pour ajouter ou modifier des traductions pour tous les wikis, veuillez utiliser [https://translatewiki.net/ translatewiki.net], le projet de régionalisation de MediaWiki.",
+       "translateinterface": "Pour ajouter ou modifier des traductions pour tous les wikis, veuillez utiliser [https://translatewiki.net/ translatewiki.net], le projet de localisation linguistique de MediaWiki.",
        "cascadeprotected": "Cette page est protégée contre les modifications car elle est transcluse par {{PLURAL:$1|la page suivante, qui a été protégée|les pages suivantes, qui ont été protégées}} avec l’option « protection en cascade » activée :\n$2",
        "namespaceprotected": "Vous n’avez pas la permission de modifier les pages de l’espace de noms « <strong>$1</strong> ».",
        "customcssprotected": "Vous n’avez pas la permission de modifier cette page de CSS, car elle contient les paramètres personnels d’un autre utilisateur.",
        "mycustomjsprotected": "Vous n’avez pas le droit de modifier cette page JavaScript.",
        "myprivateinfoprotected": "Vous n’avez pas le droit de modifier vos informations personnelles.",
        "mypreferencesprotected": "Vous n’avez pas le droit de modifier vos préférences.",
-       "ns-specialprotected": "Les pages dans l’espace de noms « {{ns:special}} » ne peuvent pas être modifiées.",
+       "ns-specialprotected": "Les pages spéciales ne peuvent pas être modifiés.",
        "titleprotected": "Ce titre a été protégé contre toute création par [[User:$1|$1]].\nLe motif fourni est <em>$2</em>.",
        "filereadonlyerror": "Impossible de modifier le fichier « $1 » parce que le répertoire de fichiers « $2 » est en lecture seule.\n\nL’administrateur système qui l’a verrouillé a fourni ce motif : « $3 ».",
        "invalidtitle-knownnamespace": "Titre non valide avec l’espace de noms « $2 » et l’intitulé « $3 »",
        "pt-createaccount": "Créer un compte",
        "pt-userlogout": "Se déconnecter",
        "php-mail-error-unknown": "Erreur inconnue dans la fonction <code>mail()</code> de PHP.",
-       "user-mail-no-addy": "Tenté d'envoyer un courriel sans adresse de courriel",
-       "user-mail-no-body": "Essai d'envoi d'un courriel avec un corps vide ou déraisonnablement court.",
+       "user-mail-no-addy": "Impossible d’envoyer un courriel sans adresse de courriel.",
+       "user-mail-no-body": "Essai d’envoi d’un courriel avec un corps vide ou anormalement court.",
        "changepassword": "Changer de mot de passe",
-       "resetpass_announce": "Pour terminer l'enregistrement, vous devez fournir un nouveau mot de passe.",
+       "resetpass_announce": "Pour terminer votre inscription, vous devez fournir un nouveau mot de passe.",
        "resetpass_text": "<!-- Ajoutez le texte ici -->",
        "resetpass_header": "Changer le mot de passe du compte",
        "oldpassword": "Ancien mot de passe :",
        "changepassword-success": "Votre mot de passe a été modifié !",
        "changepassword-throttled": "Vous avez fait trop de tentatives de connexion récemment.\nVeuillez attendre $1 avant de réessayer.",
        "botpasswords": "Mots de passe de robots",
-       "botpasswords-summary": "<em>Mots de passe de robots</em> permet d’accéder à un compte utilisateur via l’API sans utiliser les identifiants de connexion principaux. Les droits utilisateur disponibles en étant connecté avec un mot de passe robot peuvent être réduits.\n\nSi vous ne voyez pas pourquoi vous voudriez faire cela, c’est que vous n’en avez pas besoin. Personne ne devrait jamais vous demander d’en générer un et de le lui donner.",
+       "botpasswords-summary": "Les <em>mots de passe de robots</em> permettent d’accéder à un compte utilisateur via l’API sans utiliser les identifiants de connexion principaux. Les droits utilisateur disponibles en étant connecté avec un mot de passe robot peuvent être réduits.\n\nSi vous ne voyez pas pourquoi vous voudriez faire cela, c’est que vous n’en avez pas besoin. Personne ne devrait jamais vous demander d’en générer un et de le lui donner.",
        "botpasswords-disabled": "Les mots de passe robots sont désactivés.",
        "botpasswords-no-central-id": "Pour utiliser les mots de passe de robots, vous devez être connecté à un compte centralisé.",
        "botpasswords-existing": "Mots de passe de robots existants",
        "botpasswords-label-delete": "Supprimer",
        "botpasswords-label-resetpassword": "Réinitialiser le mot de passe",
        "botpasswords-label-grants": "Droits applicables :",
-       "botpasswords-help-grants": "Chaque droit donne accès aux droits utilisateurs listés qu’a déjà un compte. Voyez le [[Special:ListGrants|tableau des droits]] pour plus d’information.",
+       "botpasswords-help-grants": "Chaque droit accordé donne accès à la liste des droits utilisateurs dont l’utilisateur dispose déjà. Voyez le [[Special:ListGrants|tableau des droits]] pour plus d’informations.",
        "botpasswords-label-restrictions": "Restrictions d’utilisation :",
        "botpasswords-label-grants-column": "Accordé",
        "botpasswords-bad-appid": "Le nom de robot « $1 » n’est pas valide.",
        "passwordreset-text-one": "Remplissez ce formulaire pour réinitialiser votre mot de passe.",
        "passwordreset-text-many": "{{PLURAL:$1|Remplissez un des champs pour recevoir un mot de passe temporaire par courriel.}}",
        "passwordreset-disabled": "La réinitialisation des mots de passe a été désactivée sur ce wiki.",
-       "passwordreset-emaildisabled": "Les fonctionnalités e-mail ont été désactivées sur ce wiki.",
+       "passwordreset-emaildisabled": "Les fonctionnalités de courriel ont été désactivées sur ce wiki.",
        "passwordreset-username": "Nom d'utilisateur :",
        "passwordreset-domain": "Domaine :",
        "passwordreset-capture": "Voir le courriel résultant ?",
-       "passwordreset-capture-help": "Si vous cochez cette case, le courriel (avec le mot de passe temporaire) vous sera affiché en même temps qu'il sera envoyé à l'utilisateur.",
+       "passwordreset-capture-help": "Si vous cochez cette case, le courriel (avec le mot de passe temporaire) vous sera affiché en même temps qu’il sera envoyé à l’utilisateur.",
        "passwordreset-email": "Adresse de courriel :",
        "passwordreset-emailtitle": "Détails du compte sur {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Quelqu'un (probablement vous, depuis l'adresse IP $1) a demandé un réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
-       "passwordreset-emailtext-user": "L'utilisateur $1 sur {{SITENAME}} a demandé un réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
-       "passwordreset-emailelement": "Nom d'utilisateur : \n$1\n\nMot de passe temporaire : \n$2",
+       "passwordreset-emailtext-ip": "Quelqu’un (probablement vous, depuis l’adresse IP $1) a demandé un réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
+       "passwordreset-emailtext-user": "Lutilisateur $1 sur {{SITENAME}} a demandé un réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. Vous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
+       "passwordreset-emailelement": "Nom dutilisateur : \n$1\n\nMot de passe temporaire : \n$2",
        "passwordreset-emailsentemail": "Si cette adresse de courriel est associée à votre compte, alors un courriel de réinitialisation de mot de passe sera envoyé.",
        "passwordreset-emailsentusername": "S’il y a une adresse de courriel associée à ce nom d’utilisateur, alors un courriel de réinitialisation de mot de passe sera envoyé.",
        "passwordreset-emailsent-capture": "Un courriel de réinitialisation de mot de passe a été envoyé, qui est affiché ci-dessous.",
-       "passwordreset-emailerror-capture": "Un courriel de réinitialisation de mot de passe a été généré, qui est affiché ci-dessous, mais l'envoi à l'{{GENDER:$2|utilisateur|utilisatrice}} a échoué : $1",
+       "passwordreset-emailerror-capture": "Un courriel de réinitialisation de mot de passe a été généré, qui est affiché ci-dessous, mais l’envoi à l’{{GENDER:$2|utilisateur|utilisatrice}} a échoué : $1",
        "passwordreset-emailsent-capture2": "{{PLURAL:$1|Le courriel de réinitialisation du mot de passe a été envoyé|Les courriels de réinitialisation du mot de passe ont été envoyés}}. {{PLURAL:$1|Le nom d’utilisateur et le mot de passe sont affichés|La liste des noms d’utilisateur et mots de passe est affichée}} ci-dessous.",
        "passwordreset-emailerror-capture2": "L’envoi de courriel à {{GENDER:$2|l’utilisateur|l’utilisatrice}} a échoué : $1 {{PLURAL:$3|Le nom d’utilisateur et le mot de passe sont affichés|La liste des noms d’utilisateur et des mots de passe est affichée}} ci-dessous.",
        "passwordreset-nocaller": "Un appelant doit être fourni",
        "passwordreset-nosuchcaller": "L’appelant n’existe pas : $1",
-       "passwordreset-ignored": "La réinitialisation du mot de passe n’a pas été gérée. Peut-être qu'aucun fournisseur n’a été configuré ?",
+       "passwordreset-ignored": "La réinitialisation du mot de passe n’a pas été gérée. Peut-être quaucun fournisseur n’a été configuré ?",
        "passwordreset-invalideamil": "Adresse de messagerie non valide",
-       "passwordreset-nodata": "Ni nom d’utilisateur ni adresse de messagerie n’ont été fournis",
+       "passwordreset-nodata": "Ni un nom d’utilisateur ni une adresse de messagerie n’a  été fourni",
        "changeemail": "Changer ou supprimer l’adresse de courriel",
        "changeemail-header": "Complétez ce formulaire pour modifier votre adresse de courriel. Si vous voulez supprimer l’association d’une adresse de courriel avec votre compte, laissez la nouvelle adresse de courriel vide lors de la soumission du formulaire.",
        "changeemail-passwordrequired": "Vous devrez saisir votre mot de passe pour confirmer cette modification.",
        "italic_tip": "Texte italique",
        "link_sample": "Titre du lien",
        "link_tip": "Lien interne",
-       "extlink_sample": "http://www.example.com titre du lien",
+       "extlink_sample": "http://www.example.com/ titre du lien",
        "extlink_tip": "Lien externe (n'oubliez pas le préfixe http://)",
        "headline_sample": "Texte du titre",
        "headline_tip": "Sous-titre niveau 2",
        "preview": "Prévisualisation",
        "showpreview": "Prévisualiser",
        "showdiff": "Voir les modifications",
-       "blankarticle": "<strong>Attention :</strong> La page que vous créez est vide.\nSi vous cliquez de nouveau sur « {{int:savearticle}} », la page sera créée sans aucun contenu.",
-       "anoneditwarning": "<strong>Attention :</strong> Vous n’êtes pas connecté. Votre adresse IP sera visible de tout le monde si vous faites des modifications. Si vous <strong>[$1 vous connectez]</strong> ou <strong>[$2 créez un compte]</strong>, vos modifications seront attribuées à votre nom d’utilisateur, entre autres avantages.",
-       "anonpreviewwarning": "''Vous n’êtes pas identifié{{GENDER:||e}}. Sauvegarder enregistrera votre adresse IP dans l’historique des modifications de la page.''",
-       "missingsummary": "'''Rappel :''' vous n'avez pas encore fourni le résumé de votre modification.\nSi vous cliquez de nouveau sur le bouton « {{int:savearticle}} », la publication sera faite sans nouvel avertissement.",
-       "selfredirect": "<strong>Attention :</strong> Vous êtes en train de rediriger la page vers elle-même.\nVous pouvez avoir spécifié la mauvaise cible pour la redirection, ou vous modifiez peut-être la mauvaise page.\nSi vous cliquez de nouveau sur « {{int:savearticle}} », la redirection sera créée tout de même.",
+       "blankarticle": "<strong>Attention :</strong> la page que vous créez est vide.\nSi vous cliquez de nouveau sur « {{int:savearticle}} », la page sera créée sans aucun contenu.",
+       "anoneditwarning": "<strong>Attention :</strong> vous n’êtes pas connecté. Votre adresse IP sera visible de tout le monde si vous faites des modifications. Si vous <strong>[$1 vous connectez]</strong> ou <strong>[$2 créez un compte]</strong>, vos modifications seront attribuées à votre nom d’utilisateur, avec d'autres avantages.",
+       "anonpreviewwarning": "<em>Vous n’êtes pas connecté{{GENDER:||e}}. Sauvegarder enregistrera votre adresse IP dans l’historique des modifications de la page.</em>",
+       "missingsummary": "<strong>Rappel :</strong> vous n’avez pas encore fourni le résumé de votre modification.\nSi vous cliquez de nouveau sur le bouton « {{int:savearticle}} », vos modifications seront sauvegardées sans résumé.",
+       "selfredirect": "<strong>Attention :</strong> vous êtes en train de rediriger la page vers elle-même.\nVous pouvez avoir spécifié la mauvaise cible pour la redirection, ou vous modifiez peut-être la mauvaise page.\nSi vous cliquez de nouveau sur « {{int:savearticle}} », la redirection sera tout de même créée.",
        "missingcommenttext": "Veuillez entrer un commentaire ci-dessous.",
-       "missingcommentheader": "<strong>Rappel :</strong> Vous n’avez pas fourni de sujet pour ce commentaire.\nSi vous cliquez de nouveau sur « {{int:Savearticle}} », votre modification sera enregistrée sans sujet.",
+       "missingcommentheader": "<strong>Rappel :</strong> vous n’avez pas fourni de sujet pour ce commentaire.\nSi vous cliquez de nouveau sur « {{int:Savearticle}} », votre modification sera enregistrée sans sujet.",
        "summary-preview": "Aperçu du résumé :",
        "subject-preview": "Aperçu du sujet :",
        "previewerrortext": "Une erreur s’est produite lors de la tentative de prévisualisation de vos modifications.",
        "whitelistedittext": "Vous devez vous $1 pour avoir la permission de modifier le contenu.",
        "confirmedittext": "Vous devez confirmer votre adresse de courriel avant de modifier les pages.\nVeuillez entrer et valider votre adresse de courriel dans vos [[Special:Preferences|préférences]].",
        "nosuchsectiontitle": "Impossible de trouver la section",
-       "nosuchsectiontext": "Vous avez essayé de modifier une section qui n'existe pas.\nElle a peut-être été déplacée ou supprimée depuis que vous avez lu cette page.",
+       "nosuchsectiontext": "Vous avez essayé de modifier une section qui n’existe pas.\nElle a peut-être été déplacée ou supprimée pendant que vous la consultiez.",
        "loginreqtitle": "Connexion nécessaire",
        "loginreqlink": "connecter",
        "loginreqpagetext": "Vous devez vous $1 pour voir les autres pages.",
        "accmailtitle": "Mot de passe envoyé.",
        "accmailtext": "Un mot de passe généré aléatoirement pour [[User talk:$1|$1]] a été envoyé à $2.\nIl peut être modifié sur la page ''[[Special:ChangePassword|Changement de mot de passe]]'' après connexion.",
        "newarticle": "(Nouveau)",
-       "newarticletext": "Vous avez suivi un lien vers une page qui n’existe pas encore. \nAfin de créer cette page, entrez votre texte dans la boîte ci-après (vous pouvez consulter [$1 la page d’aide] pour plus d’informations). \nSi vous êtes arrivé{{GENDER:||e}} ici par erreur, cliquez sur le bouton '''retour''' de votre navigateur.",
+       "newarticletext": "Vous avez suivi un lien vers une page qui n’existe pas encore. \nAfin de créer cette page, entrez votre texte dans la boîte ci-après (vous pouvez consulter [$1 la page d’aide] pour plus d’informations). \nSi vous êtes arrivé{{GENDER:||e}} ici par erreur, cliquez sur le bouton <strong>Retour</strong> de votre navigateur.",
        "anontalkpagetext": "----\n<em>Vous êtes sur la page de discussion d’un utilisateur anonyme qui n’a pas encore créé de compte ou qui n’en utilise pas</em>.\nPour cette raison, nous devons utiliser son adresse IP pour l’identifier.\nUne adresse IP peut être partagée par plusieurs utilisateurs.\nSi vous êtes un{{GENDER:||e|}} utilisat{{GENDER:|eur|rice|eur}} anonyme et si vous constatez que des commentaires qui ne vous concernent pas vous ont été adressés, vous pouvez [[Special:CreateAccount|créer un compte]] ou [[Special:UserLogin|vous connecter]] afin d’éviter toute confusion future avec d’autres contributeurs anonymes.",
        "noarticletext": "Il n’y a pour l’instant aucun texte sur cette page.\nVous pouvez [[Special:Search/{{PAGENAME}}|lancer une recherche sur ce titre]] dans les autres pages,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechercher dans les opérations liées]\nou [{{fullurl:{{FULLPAGENAME}}|action=edit}} créer cette page]</span>.",
-       "noarticletext-nopermission": "Il n'y a pour l'instant aucun texte sur cette page.\nVous pouvez [[Special:Search/{{PAGENAME}}|faire une recherche sur ce titre]] dans les autres pages,\nou <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechercher dans les journaux associés]</span>.",
-       "missing-revision": "La révision n° $1 de la page intitulée Â« {{FULLPAGENAME}} Â» n'existe pas.\n\nCela survient en général en suivant un lien historique obsolète vers une page qui a été supprimée.\nVous pouvez trouver plus de détails dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
-       "userpage-userdoesnotexist": "Le compte utilisateur « <nowiki>$1</nowiki> » n'est pas enregistré. Veuillez vérifier que vous voulez créer cette page.",
+       "noarticletext-nopermission": "Il n'y a pour l'instant aucun texte sur cette page.\nVous pouvez [[Special:Search/{{PAGENAME}}|faire une recherche sur ce titre]] dans les autres pages,\nou <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechercher dans les journaux associés]</span>, mais vous n'avez pas la permission de créer cette page.",
+       "missing-revision": "La révision nº $1 de la page intitulée Â« {{FULLPAGENAME}} Â» nâ\80\99existe pas.\n\nCela survient en général en suivant un lien historique obsolète vers une page qui a été supprimée.\nVous pouvez trouver plus de détails dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
+       "userpage-userdoesnotexist": "Le compte utilisateur « <nowiki>$1</nowiki> » nest pas enregistré. Veuillez vérifier que vous voulez créer cette page.",
        "userpage-userdoesnotexist-view": "Le compte utilisateur « $1 » n'est pas enregistré.",
        "blocked-notice-logextract": "Cet utilisateur est actuellement bloqué.\nLa dernière entrée du journal des blocages est indiquée ci-dessous à titre d’information :",
-       "clearyourcache": "<strong>Note :</strong> après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.\n* <strong>Firefox / Safari :</strong> Maintenez la touche <em>Maj</em> (<em>Shift</em>) en cliquant sur le bouton <em>Actualiser</em> ou pressez <em>Ctrl-F5</em> ou <em>Ctrl-R</em> (<em>⌘-R</em> sur un Mac) ;\n* <strong>Google Chrome :</strong> Appuyez sur <em>Ctrl-Maj-R</em> (<em>⌘-Shift-R</em> sur un Mac) ;\n* <strong>Internet Explorer :</strong> Maintenez la touche <em>Ctrl</em> en cliquant sur le bouton <em>Actualiser</em> ou pressez <em>Ctrl-F5</em> ;\n* <strong>Opera :</strong> Allez dans <em>Menu → Settings</em> (<em>Opera → Préférences</em> sur un Mac) et ensuite à <em>Confidentialité & sécurité → Effacer les données d'exploration → Images et fichiers en cache</em>.",
-       "usercssyoucanpreview": "'''Astuce :''' utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille CSS avant de l'enregistrer.",
-       "userjsyoucanpreview": "'''Astuce :''' utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille JavaScript avant de l'enregistrer.",
-       "usercsspreview": "'''Rappelez-vous que vous n'êtes qu'en train de prévisualiser votre propre feuille CSS.'''\n'''Elle n'a pas encore été enregistrée !'''",
-       "userjspreview": "'''Rappelez-vous que vous êtes en train de visualiser ou de tester votre code JavaScript et qu'il n'a pas encore été enregistré !'''",
-       "sitecsspreview": "'''Souvenez-vous que vous êtes seulement en train de prévisualiser cette feuille de style.'''\n'''Elle n'a pas encore été enregistrée !'''",
-       "sitejspreview": "'''Souvenez-vous que vous êtes seulement en train de prévisualiser ce code JavaScript.'''\n'''Il n'a pas encore été enregistré !'''",
-       "userinvalidcssjstitle": "'''Attention :''' il n'existe pas d'habillage « $1 ». Rappelez-vous que les pages personnelles avec extensions .css et .js utilisent des titres en minuscules, par exemple {{ns:user}}:Foo/vector.css et non {{ns:user}}:Foo/Vector.css.",
+       "clearyourcache": "<strong>Note :</strong> après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.\n* <strong>Firefox / Safari :</strong> maintenez la touche <em>Maj</em> (<em>Shift</em>) en cliquant sur le bouton <em>Actualiser</em> ou pressez <em>Ctrl-F5</em> ou <em>Ctrl-R</em> (<em>⌘-R</em> sur un Mac) \n* <strong>Google Chrome :</strong> appuyez sur <em>Ctrl-Maj-R</em> (<em>⌘-Shift-R</em> sur un Mac) \n* <strong>Internet Explorer :</strong> maintenez la touche <em>Ctrl</em> en cliquant sur le bouton <em>Actualiser</em> ou pressez <em>Ctrl-F5</em> \n* <strong>Opera :</strong> allez dans <em>Menu → Settings</em> (<em>Opera → Préférences</em> sur un Mac) et ensuite à <em>Confidentialité & sécurité → Effacer les données d’exploration → Images et fichiers en cache</em>.",
+       "usercssyoucanpreview": "<strong>Astuce :</strong> utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille CSS avant de l’enregistrer.",
+       "userjsyoucanpreview": "<strong>Astuce :</strong> utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille JavaScript avant de l’enregistrer.",
+       "usercsspreview": "<strong>Rappelez-vous que vous ne faites que prévisualiser votre propre feuille CSS. \nElle n’a pas encore été enregistrée !</strong>",
+       "userjspreview": "<strong>Rappelez-vous que vous ne faites que visualiser ou tester votre code JavaScript.\nIl n’a pas encore été enregistré !</strong>",
+       "sitecsspreview": "<strong>Rappelez-vous que vous ne faites que prévisualiser cette feuille de style. \nElle n’a pas encore été enregistrée !</strong>",
+       "sitejspreview": "<strong>Rappelez-vous que vous ne faites que prévisualiser ce code JavaScript. \nIl n’a pas encore été enregistré !</strong>",
+       "userinvalidcssjstitle": "<strong>Attention :</strong> il n’existe pas d’habillage « $1 ». \nLes pages personnelles avec extensions .css et .js utilisent des titres en minuscules, par exemple {{ns:user}}:Foo/vector.css et non {{ns:user}}:Foo/Vector.css.",
        "updated": "(Mis à jour)",
-       "note": "'''Note :'''",
-       "previewnote": "'''Rappelez-vous que ce n'est qu'une prévisualisation.'''\nVos modifications n'ont pas encore été enregistrées !",
+       "note": "<strong>Note :</strong>",
+       "previewnote": "<strong>Rappelez-vous que ce n’est qu’une prévisualisation.</strong>\nVos modifications n’ont pas encore été enregistrées !",
        "continue-editing": "Aller à la zone de modification",
-       "previewconflict": "Cette prévisualisation montre le texte de la boîte supérieure de modification tel qu'il apparaîtra si vous choisissez de le publier.",
+       "previewconflict": "Cette prévisualisation montre le texte de la boîte supérieure de modification tel quil apparaîtra si vous choisissez de le publier.",
        "session_fail_preview": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\nVous avez peut-être été déconnecté. <strong>Veuillez vérifier que vous êtes toujours connecté et réessayer.</strong>\nSi cela échoue de nouveau, essayez en vous [[Special:UserLogout|déconnectant]], puis en vous reconnectant, et vérifiez que votre navigateur accepte les cookies de ce site.",
        "session_fail_preview_html": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\n<em>Parce que {{SITENAME}} a activé le HTML brut, la prévisualisation est masquée afin de prévenir les attaques par JavaScript.</em>\n\n<strong>Si la tentative de modification est légitime, veuillez réessayer.</strong>\nSi cela échoue de nouveau, [[Special:UserLogout|déconnectez-vous]], puis reconnectez-vous, et vérifiez que votre navigateur accepte les cookies de ce site.",
-       "token_suffix_mismatch": "'''Votre modification n'a pas été acceptée car votre navigateur a mal codé les caractères de ponctuation dans l'identifiant de modification.'''\nCe rejet est nécessaire pour empêcher la corruption du texte de la page.\nCe problème se produit parfois lorsque vous utilisez un serveur mandataire anonyme problématique basé sur le web.",
-       "edit_form_incomplete": "'''Certaines parties du formulaire de modification n'ont pas atteint le serveur, vérifiez que vos modifications sont intactes et essayez à nouveau.'''",
+       "token_suffix_mismatch": "<strong>Votre modification n’a pas été acceptée car votre navigateur a mal codé les caractères de ponctuation dans l’identifiant de modification.</strong>\nCe rejet est nécessaire pour empêcher la corruption du texte de la page.\nCe problème se produit parfois lorsque vous utilisez un serveur mandataire anonyme problématique basé sur le web.",
+       "edit_form_incomplete": "<strong>Certaines parties du formulaire de modification n’ont pas atteint le serveur, vérifiez que vos modifications sont intactes et essayez à nouveau.</strong>",
        "editing": "Modification de $1",
        "creating": "Création de $1",
        "editingsection": "Modification de $1 (section)",
        "editingcomment": "Modification de $1 (nouvelle section)",
        "editconflict": "Conflit de modification : $1",
-       "explainconflict": "Cette page a été changée après que vous ayez commencé à la modifier.\nLa zone de modification supérieure contient le texte tel qu'il est actuellement enregistré dans la base de données.\nVos modifications apparaissent dans la zone de modification inférieure.\nVous allez devoir fusionner vos modifications dans le texte existant.\n'''Seul''' le texte de la zone supérieure sera sauvegardé si vous cliquez sur « {{int:savearticle}} ».",
+       "explainconflict": "Cette page a été changée après que vous ayez commencé à la modifier.\nLa zone de modification supérieure contient le texte tel qu’il est actuellement enregistré dans la base de données.\nVos modifications apparaissent dans la zone de modification inférieure.\nVous allez devoir fusionner vos modifications dans le texte existant.\n<strong>Seul</strong> le texte de la zone supérieure sera sauvegardé si vous cliquez sur « {{int:savearticle}} ».",
        "yourtext": "Votre texte",
        "storedversion": "La version enregistrée",
-       "nonunicodebrowser": "'''Attention : Votre navigateur ne supporte pas l'Unicode.'''\nUne solution de rechange a été trouvée pour vous permettre de modifier en toute sûreté une page : les caractères non-ASCII apparaîtront dans votre boîte de modification en tant que codes hexadécimaux. Vous devriez utiliser un navigateur plus récent.",
-       "editingold": "'''Attention : vous êtes en train de modifier une ancienne version de cette page.\nSi vous la publiez, toutes les modifications effectuées depuis cette version seront perdues.'''",
+       "nonunicodebrowser": "<strong>Attention : votre navigateur ne supporte pas l’Unicode.</strong>\nUn palliatif est en place vous permettant de modifier les pages en toute sécurité, faisant apparaître les caractères non-ASCII  sous forme hexadécimale dans la boîte de modification.",
+       "editingold": "<strong>Attention : vous êtes en train de modifier une ancienne version de cette page.</strong>\nSi vous la publiez, toutes les modifications effectuées depuis cette version seront perdues.",
        "yourdiff": "Différences",
-       "copyrightwarning": "Toutes les contributions à {{SITENAME}} sont considérées comme publiées sous les termes de la $2 (voir $1 pour plus de détails). Si vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.<br />\nVous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public, ou d’une ressource libre. '''N’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !'''",
-       "copyrightwarning2": "Toutes les contributions à {{SITENAME}} peuvent être modifiées ou supprimées par d’autres utilisateurs. Si vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.<br \n/>Vous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public, ou d’une ressource libre. (voir $1 pour plus de détails).\n'''N’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !'''",
+       "copyrightwarning": "Toutes les contributions à {{SITENAME}} sont considérées comme publiées sous les termes de la $2 (voir $1 pour plus de détails). \nSi vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.<br /> \nVous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public ou d’une ressource libre similaire. \n<strong>N’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !</strong>",
+       "copyrightwarning2": "Notez bien que toutes les contributions à {{SITENAME}} peuvent être modifiées, transformées ou supprimées par d’autres utilisateurs. \nSi vous ne désirez pas que vos écrits soient modifiés contre votre gré, merci de ne pas les soumettre ici.<br /> \nVous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public, ou d’une ressource libre. (voir $1 pour plus de détails).\n<strong>N’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !</strong>",
        "editpage-cannot-use-custom-model": "Le modèle de contenu de cette page ne peut pas être modifié.",
        "longpageerror": "<strong>Erreur : Le texte que vous avez soumis fait {{PLURAL:$1|un Kio|$1 Kio}}, ce qui dépasse la limite fixée à {{PLURAL:$2|un Kio|$2 Kio}}.</strong>\nIl ne peut pas être sauvegardé.",
        "readonlywarning": "<strong>AVERTISSEMENT : la base de données a été verrouillée pour des opérations de maintenance. Vous ne pouvez donc pas publier vos modifications pour l’instant.</strong>\nVous pouvez copier et coller votre texte dans un fichier texte et l’enregistrer pour plus tard.\n\nL’administrateur système ayant verrouillé la base de données a donné l’explication suivante : $1",
        "nocreatetext": "{{SITENAME}} a restreint la possibilité de créer de nouvelles pages.\nVous pouvez revenir en arrière et modifier une page existante, ou bien [[Special:UserLogin|vous connecter ou créer un compte]].",
        "nocreate-loggedin": "Vous n'avez pas la permission de créer de nouvelles pages.",
        "sectioneditnotsupported-title": "Modification de section non prise en charge",
-       "sectioneditnotsupported-text": "La modification d'une section n'est pas prise en charge pour cette page.",
+       "sectioneditnotsupported-text": "La modification d’une section n’est pas prise en charge pour cette page.",
        "permissionserrors": "Erreur de permissions",
        "permissionserrorstext": "Vous n'avez pas la permission d'effectuer l'opération demandée pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :",
        "permissionserrorstext-withaction": "Vous ne pouvez pas $2, pour {{PLURAL:$1|la raison suivante|les raisons suivantes}} :",
        "contentmodelediterror": "Vous ne pouvez pas modifier cette révision car son modèle de contenu est <code>$1</code>, ce qui diffère du modèle de contenu actuel de la page <code>$2</code>.",
-       "recreate-moveddeleted-warn": "'''Attention : vous êtes en train de recréer une page qui a été précédemment supprimée.'''\n\nAssurez-vous qu'il est pertinent de poursuivre les modifications sur cette page. Le journal des suppressions et des déplacements est affiché ci-dessous :",
-       "moveddeleted-notice": "Cette page a été supprimée. Le journal des suppressions et des déplacements est affiché ci-dessous pour référence.",
-       "moveddeleted-notice-recent": "Désolé, cette page a été récemment supprimée (dans les dernières 24 heures).\nLes journaux des suppressions et des renommages pour la page sont fournis ci-dessous à titre d’information.",
+       "recreate-moveddeleted-warn": "<strong>Attention : vous êtes en train de recréer une page qui a été précédemment supprimée.</strong>\n\nAssurez-vous qu'il est pertinent de poursuivre les modifications sur cette page. \nLe journal des suppressions et des déplacements pour cette page est affiché ci-dessous à titre d'information :",
+       "moveddeleted-notice": "Cette page a été supprimée. \nLe journal des suppressions et des déplacements de la page est affiché ci-dessous pour référence.",
+       "moveddeleted-notice-recent": "Désolé, cette page a été récemment supprimée (dans les dernières 24 heures).\nLes journaux des suppressions et des renommages pour la page sont fournis ci-dessous pour référence.",
        "log-fulllog": "Voir le journal complet",
-       "edit-hook-aborted": "Échec de la modification par une extension.\nCause inconnue",
-       "edit-gone-missing": "N'a pas pu mettre à jour la page.\nIl semble qu'elle ait été supprimée.",
+       "edit-hook-aborted": "Échec de la modification par une extension.\nAucune explication n’a été retournée.",
+       "edit-gone-missing": "N’a pas pu mettre à jour la page.\nIl semble qu’elle ait été supprimée.",
        "edit-conflict": "Conflit de modification.",
-       "edit-no-change": "Votre modification a été ignorée car aucun changement n'a été fait au texte.",
+       "edit-no-change": "Votre modification a été ignorée car aucun changement na été fait au texte.",
        "postedit-confirmation-created": "La page a été créée.",
        "postedit-confirmation-restored": "La page a été restaurée.",
        "postedit-confirmation-saved": "Votre modification a été enregistrée.",
-       "edit-already-exists": "La nouvelle page n'a pas pu être créée.\nElle existe déjà.",
+       "edit-already-exists": "La nouvelle page na pas pu être créée.\nElle existe déjà.",
        "defaultmessagetext": "Message par défaut",
        "content-failed-to-parse": "Échec de l’analyse syntaxique du contenu de $2 pour le modèle $1 : $3",
        "invalid-content-data": "Données du contenu non valides",
        "content-model-css": "CSS",
        "content-json-empty-object": "Objet vide",
        "content-json-empty-array": "Tableau vide",
+       "deprecated-self-close-category": "Pages utilisant des balises HTML auto-fermantes non valides",
+       "deprecated-self-close-category-desc": "La page contient des balises HTML auto-fermantes non valides, comme <code>&lt;b/></code> ou <code>&lt;span/></code>.  Le comportement de celles-ci changera prochainement pour être en accord avec la spécification HTML5, donc leur utilisation dans le wikitexte est obsolète.",
        "duplicate-args-warning": "<strong>Avertissement :</strong> [[:$1]] appelle [[:$2]] avec plus d'une valeur pour le paramètre « $3 ». Seule la dernière valeur fournie sera utilisée.",
        "duplicate-args-category": "Pages utilisant des arguments dupliqués dans les appels de modèle",
        "duplicate-args-category-desc": "La page contient des appels de modèle qui utilisent des arguments dupliqués, comme <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ou <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
-       "expensive-parserfunction-warning": "Attention : cette page contient de trop nombreux appels à des fonctions coûteuses de l'analyseur syntaxique.\n\nIl devrait y avoir moins de $2 appel{{PLURAL:$2||s}}, alors qu'il y en a maintenant $1.",
+       "expensive-parserfunction-warning": "<strong>Attention :</strong> cette page contient de trop nombreux appels à des fonctions coûteuses de l’analyseur syntaxique.\n\nIl devrait y avoir moins de $2 appel{{PLURAL:$2||s}}, alors qu’il y en a maintenant $1.",
        "expensive-parserfunction-category": "Pages avec trop d'appels dispendieux de fonctions de l'analyseur syntaxique",
-       "post-expand-template-inclusion-warning": "Attention : Cette page contient trop d'inclusions de modèles. Certaines inclusions ne seront pas effectuées.",
+       "post-expand-template-inclusion-warning": "<strong>Attention :</strong> cette page contient trop d’inclusions de modèles. Certaines inclusions ne seront pas effectuées.",
        "post-expand-template-inclusion-category": "Pages contenant trop d'inclusions de modèles",
-       "post-expand-template-argument-warning": "Attention : Cette page contient au moins un paramètre de modèle dont l'inclusion est rendue impossible. Après extension, celui-ci aurait produit un résultat trop long, il n'a donc pas été inclus.",
+       "post-expand-template-argument-warning": "<strong>Attention :</strong> cette page contient au moins un paramètre de modèle dont la taille après expansion est trop importante. \nCes arguments n’ont donc pas été inclus.",
        "post-expand-template-argument-category": "Pages contenant des paramètres de modèle non évalués",
        "parser-template-loop-warning": "Modèle en boucle détecté : [[$1]]",
        "parser-template-recursion-depth-warning": "Limite de profondeur des appels de modèles dépassée ($1)",
        "language-converter-depth-warning": "Limite de profondeur du convertisseur de langue dépassée ($1)",
-       "node-count-exceeded-category": "Pages où nombre de nœuds est dépassé",
-       "node-count-exceeded-category-desc": "Cette page dépasse le nombre maximal de nœuds.",
-       "node-count-exceeded-warning": "Page dépassant le nombre de nœuds",
-       "expansion-depth-exceeded-category": "Pages où la profondeur d'expansion est dépassée",
+       "node-count-exceeded-category": "Pages dépassant le nombre de nœuds maximal",
+       "node-count-exceeded-category-desc": "Ces pages dépassent le nombre maximal de nœuds.",
+       "node-count-exceeded-warning": "La page dépasse le nombre de nœuds maximal.",
+       "expansion-depth-exceeded-category": "Pages dépassant la profondeur d'expansion maximale",
        "expansion-depth-exceeded-category-desc": "La page dépasse la profondeur d’expansion maximale.",
-       "expansion-depth-exceeded-warning": "Page dépassant la profondeur d'expansion",
+       "expansion-depth-exceeded-warning": "Page dépassant la profondeur d’expansion maximale",
        "parser-unstrip-loop-warning": "Boucle non démontable détectée",
        "parser-unstrip-recursion-limit": "Limite de récursion non démontable dépassée ($1)",
        "converter-manual-rule-error": "Erreur détectée dans la règle manuelle de conversion de langue",
        "cantcreateaccount-text": "La création de compte depuis cette adresse IP (<b>$1</b>) a été bloquée par [[User:$3|$3]].\n\nLa raison donnée était ''$2''.",
        "cantcreateaccount-range-text": "La création de compte depuis les adresses IP dans la plage <strong>$1</strong>, qui comprend votre adresse IP (<strong>$4</strong>), ont été bloquées par [[User:$3|$3]].\n\nLe motif fourni par $3 est <em>$2</em>",
        "viewpagelogs": "Voir les opérations sur cette page",
-       "nohistory": "Il n'existe pas d'historique pour cette page.",
+       "nohistory": "Il n’existe pas d’historique des modifications pour cette page.",
        "currentrev": "Version actuelle",
-       "currentrev-asof": "Version actuelle en date du $1",
+       "currentrev-asof": "Version actuelle datée du $1",
        "revisionasof": "Version du $1",
-       "revision-info": "Révision de $1 par {{GENDER:$6|$2}}$7",
+       "revision-info": "Révision datée du $1 par {{GENDER:$6|$2}}$7",
        "previousrevision": "← Version précédente",
        "nextrevision": "Version suivante →",
        "currentrevisionlink": "Voir la version actuelle",
        "history-edit-tags": "Modifier les balises des révisions sélectionnées",
        "rev-deleted-comment": "(résumé de modification retiré)",
        "rev-deleted-user": "(nom d'utilisateur retiré)",
-       "rev-deleted-event": "(détails de l’entrée retirée)",
-       "rev-deleted-user-contribs": "[nom d'utilisateur ou adresse IP retiré - modification masquée sur les contributions]",
-       "rev-deleted-text-permission": "Cette version de la page a été '''effacée'''.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
+       "rev-deleted-event": "(détails de l’historique retirés)",
+       "rev-deleted-user-contribs": "[nom d’utilisateur ou adresse IP retiré – modification masquée dans les contributions]",
+       "rev-deleted-text-permission": "Cette version de la page a été <strong>effacée</strong>.\nDes détails sont disponibles dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
        "rev-suppressed-text-permission": "Cette version de la page a été <strong>masquée</strong>.\nLes détails se trouvent dans le [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} journal des masquages].",
        "rev-deleted-text-unhide": "Cette version de la page a été <strong>supprimée</strong>.\nDes détails sont disponibles dans [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} le journal des suppressions].\nVous pouvez toujours [$1 voir cette version] si vous le voulez.",
        "rev-suppressed-text-unhide": "Cette version de la page a été <strong>masquée</strong>.\nDes détails sont disponibles dans [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} le journal des masquages].\nVous pouvez toujours [$1 voir cette version] si vous le voulez.",
        "logdelete-text": "Les évènements du journal supprimés continueront à apparaître dans les journaux, mais une partie de leur contenu sera indisponible au public.",
        "revdelete-text-others": "Les autres administrateurs seront toujours en mesure d'accéder au contenu caché et le restaurer, à moins que des restrictions supplémentaires soient fixées.",
        "revdelete-confirm": "Confirmez que vous voulez effectuer cette action, que vous en comprenez les conséquences, et que vous le faites en accord avec [[{{MediaWiki:Policy-url}}|les règles]].",
-       "revdelete-suppress-text": "La suppression ne doit être utilisée '''que''' dans les cas suivants :\n* Informations potentiellement diffamatoires\n* Informations personnelles inappropriées\n*: ''adresse, numéro de téléphone, numéro de sécurité sociale, …''",
-       "revdelete-legend": "Mettre en place des restrictions de visibilité :",
+       "revdelete-suppress-text": "La suppression ne doit être utilisée <strong>que</strong> dans les cas suivants :\n* informations potentiellement diffamatoires\n* informations personnelles inappropriées\n*: <em>adresse, numéro de téléphone, numéro de sécurité sociale, …</em>",
+       "revdelete-legend": "Mettre en place des restrictions de visibilité",
        "revdelete-hide-text": "Texte de la révision",
        "revdelete-hide-image": "Masquer le contenu du fichier",
        "revdelete-hide-name": "Masquer la cible et les paramètres",
        "lockedbyandtime": "(par $1 le $2 à $3)",
        "move-page": "Renommer $1",
        "move-page-legend": "Renommer une page",
-       "movepagetext": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom. L’ancien titre deviendra une page de redirection vers le nouveau titre. Vous pouvez mettre à jour automatiquement les redirections actuelles qui pointent vers le titre original. Si vous choisissez de ne pas le faire, assurez-vous de vérifier toute [[Special:DoubleRedirects|double redirection]] ou [[Special:BrokenRedirects|redirection cassée]]. Vous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</strong> renommée s’il existe déjà une page avec le nouveau titre, sauf si cette dernière est une simple redirection avec un historique de modifications vierge. Ceci permet de renommer une page vers sa position d’origine si le déplacement s’avère erroné.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’en avoir compris les conséquences avant de continuer.",
+       "movepagetext": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom. L’ancien titre deviendra une page de redirection vers le nouveau titre. \nVous pouvez mettre à jour automatiquement les redirections qui pointent vers le titre original. \nSi vous choisissez de ne pas le faire, assurez-vous de vérifier toute [[Special:DoubleRedirects|double redirection]] ou [[Special:BrokenRedirects|redirection cassée]]. Vous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</strong> renommée s’il existe déjà une page portant le nouveau titre, sauf si cette dernière est une simple redirection avec un historique de modifications vierge. \nCela signifie que vous pouvez de nouveau renommer une page vers sa position d’origine si vous avez fait une erreur et que vous ne pouvez pas écraser une page existante.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’avoir compris les conséquences de votre démarche avant de continuer.",
        "movepagetext-noredirectfixer": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom.\nL’ancien titre deviendra une page de redirection vers le nouveau titre.\nVérifiez bien les [[Special:DoubleRedirects|doubles redirections]] ou les [[Special:BrokenRedirects|redirections cassées]].\nVous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</strong> déplacée s’il existe déjà une page avec le nouveau titre, sauf si cette dernière a un historique de modifications vierge et est soit vide, soit une simple redirection. Ceci permet de renommer une page vers sa position d’origine si le déplacement s’avère erroné, et il est impossible d’écraser une page existante.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’en avoir compris les conséquences avant de continuer.",
        "movepagetalktext": "Si vous cochez cette case, la page de discussion associée sera automatiquement renommée, à moins qu’une page de discussion non vide existe déjà sous ce nouveau nom.\n\nDans ce cas, vous devrez renommer ou fusionner cette page de discussion manuellement si vous le désirez.",
        "moveuserpage-warning": "'''Attention :''' Vous êtes sur le point de renommer une page d’utilisateur. Veuillez noter que seule la page sera renommée et que l’utilisateur '''ne''' sera '''pas''' renommé.",
        "invalidateemail": "Annuler la confirmation de l'adresse de courriel",
        "notificationemail_subject_changed": "L’adresse courriel enregistrée sur {{SITENAME}} a été changée",
        "notificationemail_subject_removed": "L’adresse courriel enregistrée sur {{SITENAME}} a été supprimée",
-       "notificationemail_body_changed": "Quelqu’un, probablement vous, connecté depuis l’adresse IP $1, a changé l’adresse\nde courriel associée au compte « $2 » sur {{SITENAME}} en « $3 ».\n\nSi ce n’était pas vous, contactez un administrateur du site immédiatement.",
-       "notificationemail_body_removed": "Quelqu’un, probablement vous, connecté depuis l’adresse IP $1,\na supprimé l’adresse de courriel associée au compte « $2 » sur {{SITENAME}}.\n\nSi ce n’était pas vous, contactez un administrateur du site immédiatement.",
+       "notificationemail_body_changed": "Quelqu’un, probablement vous, connecté depuis l’adresse IP $1, a changé l’adresse\ncourriel associée au compte « $2 » sur {{SITENAME}} en « $3 ».\n\nSi ce n’était pas vous, contactez un administrateur du site immédiatement.",
+       "notificationemail_body_removed": "Quelqu’un, probablement vous, connecté depuis l’adresse IP $1,\na supprimé l’adresse courriel associée au compte « $2 » sur {{SITENAME}}.\n\nSi ce n’était pas vous, contactez un administrateur du site immédiatement.",
        "scarytranscludedisabled": "[La transclusion interwiki est désactivée]",
        "scarytranscludefailed": "[La récupération de modèle a échoué pour $1]",
        "scarytranscludefailed-httpstatus": "[Échec de la récupération du modèle pour  $1 : HTTP  $2 ]",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "la page n’existe pas encore",
        "mw-widgets-titleinput-description-redirect": "redirection vers $1",
-       "api-error-blacklisted": "Merci de choisir un autre titre descriptif.",
        "sessionmanager-tie": "Impossible de combiner les demandes multiples de types d’authentification : $1.",
        "sessionprovider-generic": "sessions $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessions basées sur les cookies",
        "log-action-filter-newusers": "Type de création de compte :",
        "log-action-filter-patrol": "Type de patrouille :",
        "log-action-filter-protect": "Type de protection :",
-       "log-action-filter-rights": "Type de changement de droit",
-       "log-action-filter-suppress": "Type de suppression",
+       "log-action-filter-rights": "Type de changement de droit :",
+       "log-action-filter-suppress": "Type de suppression :",
        "log-action-filter-upload": "Type de téléversement :",
        "log-action-filter-all": "Tout",
        "log-action-filter-block-block": "Blocage",
index 488bfeb..d3828ca 100644 (file)
        "special-characters-title-minus": "segno muens",
        "mw-widgets-dateinput-placeholder-day": "AAAA-MM-JJ",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
-       "api-error-blacklisted": "Volyéd chouèsir un ôtro titro dèscriptif.",
        "randomrootpage": "Pâge racena a l’hasârd"
 }
index f1451ea..24b6f55 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Obxecto baleiro",
        "content-json-empty-array": "Matriz baleira",
+       "deprecated-self-close-category": "Páxinas que usan etiquetas HTML de auto-pechado non válidas",
+       "deprecated-self-close-category-desc": "Páxinas que conteñen unha etiqueta HTML de auto-pechado non válida, como <code>&lt;b/></code> ou <code>&lt;span/></code>. O comportamento destas etiquetas vai cambiar para gardar a consistencia coa especificación HTML5, polo que o seu uso no texto wiki está desbotado.",
        "duplicate-args-warning": "<strong>Advertencia:</strong> [[:$1]] está chamando a [[:$2]] con máis dun valor para o parámetro \"$3\". Só se usará o último valor proporcionado.",
        "duplicate-args-category": "Páxinas con argumentos duplicados nas chamadas aos modelos",
        "duplicate-args-category-desc": "Esta páxina contén as chamadas aos modelos que utilizan argumentos duplicados, como <code><nowiki>{{exemplo|bar=1|bar=2}}</nowiki></code> ou <code><nowiki>{{exemplo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "a páxina aínda non existe",
        "mw-widgets-titleinput-description-redirect": "redirección cara a $1",
-       "api-error-blacklisted": "Escolla un título diferente e descritivo.",
        "sessionmanager-tie": "Non pode combinar peticións múltiples de tipos de autenticación: $1.",
        "sessionprovider-generic": "sesións $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sesións baseadas nas cookies",
        "log-action-filter-newusers": "Tipo de creación de conta:",
        "log-action-filter-patrol": "Tipo de vixilancia:",
        "log-action-filter-protect": "Tipo de protección:",
-       "log-action-filter-rights": "Tipo de cambio de dereito",
-       "log-action-filter-suppress": "Tipo de borrado",
+       "log-action-filter-rights": "Tipo de cambio de dereito:",
+       "log-action-filter-suppress": "Tipo de borrado:",
        "log-action-filter-upload": "Tipo de subida:",
        "log-action-filter-all": "Todas",
        "log-action-filter-block-block": "Bloquear",
index fbba509..0f7c1d8 100644 (file)
@@ -12,7 +12,7 @@
                ]
        },
        "underline-always": "Sinteino",
-       "underline-never": "Niu",
+       "underline-never": "𐌽𐌹 𐌰𐌹𐍅",
        "sunday": "𐌰𐍆𐌰𐍂𐍃𐌰𐌱𐌱𐌰𐍄𐍉",
        "monday": "𐌼𐌴𐌽𐌹𐌽𐍃 𐌳𐌰𐌲𐍃",
        "tuesday": "𐍄𐌴𐌹𐍅𐌹𐍃 𐌳𐌰𐌲𐍃",
        "deletethispage": "𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌴𐌹 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰",
        "protect": "𐌱𐌰𐌹𐍂𐌲𐌰𐌽",
        "protect_change": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹",
-       "protectthispage": "ð\90\8c±ð\90\8c°ð\90\8c¹ð\90\8d\82ð\90\8c² ð\90\8c¸ð\90\8d\89 ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8c°",
-       "unprotect": "ð\90\8c½ð\90\8c¹ð\90\8c±ð\90\8c°ð\90\8c¹ð\90\8d\82ð\90\8c²ð\90\8c°",
-       "unprotectthispage": "Nibaírga þo siedo",
+       "protectthispage": "ð\90\8d\86ð\90\8d\82ð\90\8c¹ð\90\8c¸ ð\90\8c¸ð\90\8c°ð\90\8c½ð\90\8c° ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8d\86",
+       "unprotect": "ð\90\8c¹ð\90\8c½ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c³ð\90\8c´ð\90\8c¹ ð\90\8c¼ð\90\8c¿ð\90\8c½ð\90\8c³",
+       "unprotectthispage": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌼𐌿𐌽𐌳 𐌸𐌹𐍃 𐌻𐌰𐌿𐌱𐌹𐍃",
        "newpage": "𐌽𐌹𐌿𐌾𐌹𐍃 𐌻𐌰𐌿𐍆𐍃",
-       "talkpage": "ð\90\8c¼ð\90\8c°ð\90\8c¸ð\90\8c»ð\90\8c°ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8c°",
+       "talkpage": "ð\90\8d\82ð\90\8d\89ð\90\8c³ð\90\8c´ð\90\8c¹ ð\90\8c±ð\90\8c¹ ð\90\8c¸ð\90\8c°ð\90\8c½ð\90\8c° ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8d\86",
        "talkpagelinktext": "𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰",
-       "specialpage": "ð\90\8c¿ð\90\8d\83ð\90\8d\83ð\90\8c¹ð\90\8c½ð\90\8c³ð\90\8c°ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89𐍃",
+       "specialpage": "ð\90\8c¿ð\90\8d\83ð\90\8d\83ð\90\8c¹ð\90\8c½ð\90\8c³ð\90\8d\83 ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8d\86𐍃",
        "personaltools": "𐍃𐍅𐌴𐍃𐌰𐌹 𐍃𐌰𐍂𐍅𐌰𐌽𐍃",
        "talk": "𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰",
        "views": "𐍃𐌹𐌿𐌽𐌴𐌹𐍃",
        "toolbox": "𐍃𐌰𐍂𐍅𐌰𐌽𐍃",
        "otherlanguages": "𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐍂𐌰𐌶𐌳𐍉𐌼",
        "redirectedfrom": "(𐌹𐍃 𐍄𐌹𐌿𐌷𐌰𐌽𐍃/𐍄𐌹𐌿𐌷𐌰𐌽𐌰 𐌷𐌹𐌳𐍂𐌴 𐍆𐍂𐌰𐌼 $1)",
-       "redirectpagesub": "ð\90\8d\84ð\90\8c°ð\90\8c¹ð\90\8cºð\90\8c¾ð\90\8c°ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89",
+       "redirectpagesub": "ð\90\8c°ð\90\8c»ð\90\8c¾ð\90\8c°ð\90\8d\82 ð\90\8c±ð\90\8d\82ð\90\8c¹ð\90\8c²ð\90\8c²ð\90\8c°ð\90\8c½ð\90\8c³ð\90\8d\83 ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8d\86ð\90\8d\83",
        "lastmodifiedat": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌸𐌰𐍄𐌰 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌸𐍃 𐍅𐌰𐍃 ($1) ($2).",
        "jumpto": "𐌲𐌰𐌲𐌲 𐌳𐌿:",
        "jumptonavigation": "𐌻𐌰𐌿𐌱𐌰𐌲𐌰𐍅𐌹𐍃𐍃𐌴𐌹𐍃",
        "nstab-project": "𐍆𐌰𐌿𐍂𐌰𐍅𐌰𐌿𐍂𐍀𐌰𐌻𐌰𐌿𐍆𐍃",
        "nstab-image": "𐍆𐌴𐌹𐌻𐌰",
        "nstab-template": "𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽𐍃",
-       "nstab-help": "𐌷𐌹𐌻𐍀𐌰",
+       "nstab-help": "𐌷𐌹𐌻𐍀𐌰𐌻𐌰𐌿𐍆𐍃",
        "nstab-category": "𐌺𐌿𐌽𐌹",
        "mainpage-nstab": "𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌴𐌹𐌽𐌹𐌻𐌰𐌿𐍆𐍃",
        "error": "𐌰𐌹𐍂𐌶𐌴𐌹",
        "sig_tip": "𐌿𐌽𐌳𐌰𐍂𐌼𐌴𐌻 𐌸𐌴𐌹𐌽𐌰 𐌼𐌹𐌸 𐍃𐍄𐌿𐌽𐌳𐌰𐌼𐌴𐌻𐌰",
        "hr_tip": "𐍂𐌰𐌹𐌷𐍄𐍃𐌱𐌰𐌿𐍂𐌳 (𐌱𐍂𐌿𐌺𐌾𐌰𐌽 𐌼𐌹𐌸 𐌽𐌹𐌿𐍆𐌰𐍂𐌿𐍃𐍃𐌿𐍃)",
        "summary": "𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐍃𐍀𐌹𐌻𐌻𐍉𐌽:",
-       "subject": "ð\90\8c·ð\90\8c°ð\90\8c¿ð\90\8c±ð\90\8c¹ð\90\8c³ð\90\8c°ð\90\8c±ð\90\8d\89ð\90\8cº𐌰:",
+       "subject": "ð\90\8c¿ð\90\8d\86ð\90\8d\85ð\90\8c°ð\90\8c¿ð\90\8d\82ð\90\8d\80𐌰:",
        "minoredit": "𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐌼𐌹𐌽𐌽𐌹𐌶𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃",
        "watchthis": "𐌰𐍄𐍅𐌹𐍄 𐌻𐌰𐌿𐌱𐌰",
        "savearticle": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌻𐌰𐌿𐍆",
        "noarticletext": "𐌽𐌿 𐌽𐌹 𐍃𐌹𐌽𐌳 𐌱𐍉𐌺𐍉𐍃 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.\n𐌼𐌰𐌲𐍄 [[Special:Search/{{PAGENAME}}|𐍃𐍉𐌺𐌾𐌰𐌽 𐌸𐌰𐍄𐌰 𐌻𐌰𐌿𐌱𐌰-𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹]] 𐌹𐌽 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐌻𐌰𐌿𐌱𐌰𐌼,  <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 𐍃𐍉𐌺𐌾𐌰𐌽 𐌲𐌰𐌷𐌰𐌷𐌾𐍉 𐌲𐌰𐍆𐌰𐍃𐍄𐍉𐍃], 𐌰𐌹𐌸𐌸𐌰𐌿 [{{fullurl:{{FULLPAGENAME}}|action=edit}} 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆.]</ span>",
        "noarticletext-nopermission": "𐌽𐌿 𐌽𐌹 𐍃𐌹𐌽𐌳 𐌱𐍉𐌺𐍉𐍃 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.\n𐌼𐌰𐌲𐍄 [[Special:Search/{{PAGENAME}}|𐍃𐍉𐌺𐌾𐌰𐌽 𐌸𐌰𐍄𐌰 𐌻𐌰𐌿𐌱𐌰-𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹]] 𐌹𐌽 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐌻𐌰𐌿𐌱𐌰𐌼, 𐌸𐌰𐌿 <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 𐍃𐍉𐌺𐌾𐌰𐌽 𐌲𐌰𐌷𐌰𐌷𐌾𐍉 𐌲𐌰𐍆𐌰𐍃𐍄𐍉𐍃]</span>, 𐌹𐌸 𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆.",
        "updated": "(Nuwisan)",
-       "previewnote": "'''𐍃𐌰𐌷 𐌹𐍃𐍄 𐍆𐌰𐌿𐍂𐍃𐌰𐌹𐍈𐌰. 𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃 𐌲𐌰𐌼𐌴𐌻𐌾𐌹𐌸 𐌽𐌹 𐌰𐍆 𐌸𐌹𐌶𐍉𐍃 𐍃𐌴𐌹𐌳𐍉𐍃!'''",
+       "previewnote": "<strong>𐌲𐌰𐌼𐌹𐌽𐌸𐌴𐌹 𐌸𐌰𐍄𐌴𐌹 𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽𐍃.</strong>\n𐌸𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌽𐌰𐌿𐌷 𐌽𐌹 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌽𐍉𐍃 𐍃𐌹𐌽𐌳!",
        "editing": "𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌰𐍆 $1",
        "creating": "𐍃𐌺𐌰𐍀𐌾𐌰𐌽𐌳𐍃/𐍃𐌺𐌰𐍀𐌾𐌰𐌽𐌳𐌴𐌹 $1",
        "editingsection": "𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌰𐍆 $1 (𐍆𐌴𐍂𐌰)",
        "last": "𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍃",
        "page_first": "frumists",
        "page_last": "𐍃𐍀𐌴𐌳𐌿𐌼𐌹𐍃𐍄𐍃",
-       "histfirst": "ð\90\8d\86ð\90\8c°ð\90\8c¿ð\90\8d\82ð\90\8c¸ð\90\8c¹ð\90\8d\83",
-       "histlast": "ð\90\8d\83ð\90\8d\80ð\90\8c´ð\90\8c³ð\90\8c¿ð\90\8c¼ð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8d\83",
+       "histfirst": "ð\90\8c°ð\90\8c»ð\90\8c¸ð\90\8c¹ð\90\8c¶ð\90\8d\89",
+       "histlast": "ð\90\8c½ð\90\8c¹ð\90\8c¿ð\90\8c¾ð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8d\89",
        "history-feed-item-nocomment": "$1 at $2",
        "rev-delundel": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌰𐌽𐌰𐍃𐌹𐌿𐌽",
        "revdel-restore": "𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌹𐍃 𐌰𐌽𐌰𐍃𐌹𐌿𐌽𐌼𐌰𐌷𐍄𐌴𐌹𐌲𐍃",
        "ncategories": "$1 {{PLURAL:$1|𐌺𐌿𐌽𐌾𐌰|𐌺𐌿𐌽𐌾𐍉𐍃}}",
        "nlinks": "$1 {{PLURAL:$1|táikjanbandi|táikjanbandja}}",
        "nmembers": "$1 {{PLURAL:$1|niutand|niutanda}}",
-       "wantedpages": "Gaírnedum seidam",
+       "wantedpages": "𐌲𐌰𐌹𐍂𐌽𐌹𐌳𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "shortpages": "𐌻𐌴𐌹𐍄𐌹𐌻𐌰 𐍃𐌴𐌹𐌳𐍉𐍃",
-       "longpages": "𐌻𐌰𐌲𐌲𐌰 𐍃𐌴𐌹𐌳𐍉𐍃",
+       "longpages": "𐌻𐌰𐌲𐌲𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "listusers": "𐍂𐌴𐌲𐌹𐍃𐍄𐍂𐌴𐍂𐌰𐌳𐌴 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐍃",
        "newpages": "𐌽𐌹𐌿𐌾𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "move": "𐌽𐌰𐌼𐌾𐌰𐌽 𐌰𐍆𐍄𐍂𐌰",
-       "movethispage": "ð\90\8d\83ð\90\8cºð\90\8c¹ð\90\8c¿ð\90\8c±ð\90\8c°ð\90\8c½ ð\90\8d\83ð\90\8c° ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89",
+       "movethispage": "ð\90\8c¼ð\90\8c¹ð\90\8c¸ð\90\8d\83ð\90\8c°ð\90\8d\84ð\90\8c´ð\90\8c¹ ð\90\8c¸ð\90\8c°ð\90\8c½ð\90\8c° ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8d\86",
        "booksources": "𐌱𐍉𐌺𐌰𐌱𐍂𐌿𐌽𐌽𐌰𐌽𐍃",
        "booksources-search-legend": "𐍃𐍉𐌺𐌴𐌹 𐌱𐍉𐌺𐌰𐌱𐍂𐌿𐌽𐌽𐌰𐌽𐍃",
        "booksources-search": "𐍃𐍉𐌺𐌴𐌹",
        "speciallogtitlelabel": "Namo:",
        "log": "𐌻𐍉𐌲𐌱𐍉𐌺𐍉𐍃",
        "all-logs-page": "𐌰𐌻𐌻𐌰 𐌻𐍉𐌲𐍉𐍃",
-       "allpages": "ð\90\8c°ð\90\8c»ð\90\8c»ð\90\8c¹ð\90\8d\83 ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³𐍉𐍃",
+       "allpages": "ð\90\8c°ð\90\8c»ð\90\8c»ð\90\8c°ð\90\8c¹ ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8c±𐍉𐍃",
        "nextpage": "𐌹𐍆𐍄𐌿𐌼𐌰 𐍃𐌴𐌹𐌳𐍉 ($1)",
-       "prevpage": "ð\90\8c°ð\90\8d\86ð\90\8d\84ð\90\8c¿ð\90\8c¼ð\90\8c° ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89 ($1)",
+       "prevpage": "ð\90\8c°ð\90\8d\86ð\90\8d\84ð\90\8c¿ð\90\8c¼ð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8d\83 ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8d\86ð\90\8d\83 ($1)",
        "allarticles": "𐌰𐌻𐌻𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "allpagessubmit": "𐌲𐌰𐌲𐌲",
        "categories": "𐌺𐌿𐌽𐌾𐌰",
        "linksearch-ns": "𐍃𐌴𐌹𐌳𐍉𐍆𐌴𐍂𐌰:",
        "emailuser": "𐍃𐌰𐌽𐌳𐌾𐌰𐌽 𐌸𐍉 𐌽𐌹𐌿𐍄𐌰𐌽𐌳 𐌱𐍉𐌺𐍉𐌼",
-       "watchlist": "ð\90\8c¼ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8d\89ð\90\8d\83 ð\90\8d\85ð\90\8c¹ð\90\8d\84ð\90\8c°ð\90\8c½ð\90\8c³ð\90\8d\83ð\90\8c»ð\90\8c´ð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8c°",
+       "watchlist": "ð\90\8d\85ð\90\8c¹ð\90\8d\84ð\90\8c°ð\90\8d\85ð\90\8c¹ð\90\8cºð\90\8d\89",
        "mywatchlist": "𐌻𐌰𐌹𐍃𐍄𐌰𐌻𐌴𐌹𐍃𐍄𐌰",
        "watch": "𐍅𐌰𐍂𐌰𐌽",
        "watchthispage": "𐍅𐌰𐍂𐌰𐌽 𐍃𐌴𐌹𐌳𐍉",
        "unwatch": "𐌽𐌹𐍅𐌰𐍂𐌰𐌽",
-       "watchlist-details": "{{PLURAL:$1|$1 seido|$1 seidona}} witáiþs inu maþleiseidam.",
+       "watchlist-details": "{{PLURAL:$1|$1 𐌻𐌰𐌿𐍆𐍃|$1 𐌻𐌰𐌿𐌱𐍉𐍃}} 𐌰𐌽𐌰 𐌸𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽, 𐌽𐌹 𐍃𐌿𐌽𐌳𐍂𐍉 𐍂𐌰𐌷𐌽𐌾𐌰𐌽𐌳𐌰 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰𐌻𐌰𐌿𐌱𐍉𐍃.",
        "watching": "Wita...",
        "unwatching": "Niwita...",
        "created": "𐌲𐌰𐍃𐌺𐌰𐍀𐌾𐌰𐌽",
-       "deletepage": "ð\90\8d\84ð\90\8c°ð\90\8c¹ð\90\8d\82ð\90\8c° ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89",
+       "deletepage": "ð\90\8d\86ð\90\8d\82ð\90\8c°ð\90\8cµð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8c´ð\90\8c¹ ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8c±ð\90\8c°",
        "delete-legend": "𐍄𐌰𐌹𐍂𐌰𐌽",
        "actioncomplete": "𐍅𐌰𐍃𐌿𐌷 𐌹𐍄𐌰 𐌲𐌰𐌿𐍃𐍄𐌹𐌿𐌷𐌰𐌽",
        "dellogpage": "𐍄𐌰𐌹𐍂𐌰 𐌰𐌹𐍂𐍅𐌱𐍉𐌺𐌰",
        "rollbacklinkcount": "𐌰𐍆𐍅𐌰𐌻𐍅𐌴𐌹 $1 {{PLURAL:$1|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃}}",
        "protectlogpage": "Log af Baírgjan",
        "prot_1movedto2": "[[$1]] skiubiþ du [[$2]]",
-       "protect-level-sysop": "ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89ð\90\8d\86ð\90\8c°ð\90\8c¸ð\90\8d\83 ð\90\8c°ð\90\8c¹ð\90\8c½ð\90\8c°ð\90\8c·ð\90\8c°",
+       "protect-level-sysop": "ð\90\8c°ð\90\8c½ð\90\8c³ð\90\8c»ð\90\8c´ð\90\8d\84ð\90\8c¹ð\90\8c¸ ð\90\8c¸ð\90\8c°ð\90\8d\84ð\90\8c°ð\90\8c¹ð\90\8c½ð\90\8c´ð\90\8c¹ ð\90\8d\82ð\90\8c´ð\90\8c¹ð\90\8cºð\90\8d\83",
        "protect-expiring": "bláuþiþ $1 (UTC)",
        "restriction-type": "Freihals:",
        "restriction-edit": "𐌼𐌰𐌹𐌳𐌾𐌰𐌽",
        "year": "𐍆𐍂𐌰𐌼 𐌾𐌴𐍂𐌰 (𐌾𐌰𐌷 𐌰𐍆𐍄𐌿𐌼𐌰):",
        "sp-contributions-newbies-sub": "Faúr niujis niutandis",
        "sp-contributions-blocklog": "Logboka af afdraúsjan",
-       "sp-contributions-talk": "Maþleiseido",
+       "sp-contributions-talk": "𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰",
        "whatlinkshere": "𐌰𐌻𐌻𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌸𐌰𐌹𐌴𐌹 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳 𐌸𐌿𐌺 𐌷𐌹𐌳𐍂𐌴",
        "whatlinkshere-title": "𐌻𐌰𐌿𐌱𐍉𐍃 𐌸𐌰𐌹𐌴𐌹 𐍄𐌰𐌹𐌺𐌽𐌾𐌰𐌽𐌳 𐌳𐌿 \"$1\"",
        "whatlinkshere-page": "𐌻𐌰𐌿𐍆𐍃:",
        "whatlinkshere-next": "{{PLURAL:$1|iftuma|iftumans $1}}",
        "whatlinkshere-links": "← táikajanbandja",
        "whatlinkshere-hidelinks": "$1 𐌲𐌰𐍅𐌹𐍃𐍃𐌴𐌹𐍃",
-       "blockip": "ð\90\8c°ð\90\8d\86ð\90\8c³ð\90\8d\82ð\90\8c°ð\90\8c¿ð\90\8d\83ð\90\8c¾ð\90\8c°ð\90\8c½ ð\90\8c½ð\90\8c¹ð\90\8c¿ð\90\8d\84ð\90\8c°ð\90\8c½ð\90\8c³ð\90\8c¹ð\90\8d\83",
+       "blockip": "ð\90\8d\86ð\90\8c°ð\90\8c¿ð\90\8d\82ð\90\8c³ð\90\8c°ð\90\8c¼ð\90\8c¼ð\90\8c´ð\90\8c¹ {{GENDER:$1|user}}",
        "ipbreason": "𐍆𐌰𐌹𐍂𐌹𐌽𐌰:",
        "ipboptions": "𐌱 𐌰𐍅𐍂𐌰:2 hours, 𐌰 𐌳𐌰𐌲𐍃:1 day, 𐌲 𐌳𐌰𐌲𐍉𐍃:3 days, 𐌰 𐍅𐌹𐌺𐍉:1 week, 𐌱 𐍅𐌹𐌺𐍉𐌽𐍃:2 weeks, 𐌰 𐌼𐌴𐌽𐍉𐌸𐍃:1 month, 𐌲 𐌼𐌴𐌽𐍉𐌸𐍉𐍃:3 months, 𐌵 𐌼𐌴𐌽𐍉𐌸𐍉𐍃:6 months, 𐌰 𐌾𐌴𐍂:1 year, 𐌹𐌽𐌿𐍄𐍂𐌹𐌲𐌲𐌴𐌽𐌳𐌴𐌹𐍃:infinite",
        "ipblocklist-submit": "Sokeiþ",
        "contribslink": "𐌱𐌹𐌰𐌿𐌺𐌰𐌹𐌽𐌴𐌹𐍃",
        "blocklogpage": "𐌻𐍉𐌲𐌱𐍉𐌺𐌰 𐌰𐍆 𐌰𐍆𐌳𐍂𐌰𐌿𐍃𐌾𐌰𐌽",
        "blocklogentry": "𐌰𐍆𐌳𐍂𐌰𐌿𐍃𐌹𐌸 [[$1]] 𐍆𐌰𐌿𐍂 $2 $3",
-       "newtitle": "ð\90\8c³ð\90\8c¿ ð\90\8c½ð\90\8c¹ð\90\8c¿ð\90\8c¾ð\90\8c¹ð\90\8d\83 ð\90\8c½ð\90\8c°ð\90\8c¼ð\90\8d\89ð\90\8d\83:",
+       "newtitle": "ð\90\8c½ð\90\8c¹ð\90\8c¿ð\90\8c¾ð\90\8c¹ ð\90\8c¿ð\90\8d\86ð\90\8c°ð\90\8d\82ð\90\8c¼ð\90\8c´ð\90\8c»ð\90\8c¹:",
        "move-watch": "𐍅𐌹𐍄𐌰𐌽 𐍃𐍉 𐍃𐌴𐌹𐌳𐍉",
        "movepagebtn": "𐍃𐌺𐌹𐌿𐌱𐌰 𐍃𐌴𐌹𐌳𐍉",
        "movelogpage": "Log af skiubans",
        "tooltip-ca-viewsource": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌷𐌰𐌱𐌰𐌹𐌸 𐌼𐌿𐌽𐌳. 𐌼𐌰𐌲𐍄 𐌸𐌹𐍃 𐌻𐌰𐌿𐌱𐌹𐍃 𐌼𐌿𐌽𐌳 𐍃𐌰𐌹𐍈𐌰𐌽.",
        "tooltip-ca-history": "𐌰𐍆𐍄𐌿𐌼𐍉𐍃 𐌲𐌰𐌱𐍉𐍄𐌴𐌹𐌽𐍉𐍃 𐌸𐌹𐍃 𐌻𐌰𐌿𐌱𐌹𐍃",
        "tooltip-ca-protect": "𐌱𐌰𐌹𐍂𐌲𐌰 𐌸𐍉 𐍃𐌴𐌹𐌳𐍉",
-       "tooltip-ca-delete": "ð\90\8d\84ð\90\8c°ð\90\8c¹ð\90\8d\82ð\90\8c°ð\90\8c½ ð\90\8d\83ð\90\8d\89 ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89",
+       "tooltip-ca-delete": "ð\90\8d\86ð\90\8d\82ð\90\8c°ð\90\8cµð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8c´ð\90\8c¹ ð\90\8c¸ð\90\8c°ð\90\8c¼ð\90\8c¼ð\90\8c° ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8c±ð\90\8c°",
        "tooltip-ca-move": "𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆",
        "tooltip-ca-watch": "𐌱𐌹𐌰𐌹𐌰𐌿𐌺 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆 𐌳𐌿 𐌸𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
        "tooltip-search": "𐍃𐍉𐌺𐌾𐌰𐌽 {{SITENAME}}",
        "tooltip-ca-nstab-user": "𐍃𐌰𐌹𐍈 𐌱𐍂𐌿𐌺𐌾𐌰𐌻𐌰𐌿𐍆",
        "tooltip-ca-nstab-special": "𐍃𐌰 𐌹𐍃𐍄 𐌿𐍃𐍃𐌹𐌽𐌳𐍃 𐌻𐌰𐌿𐍆𐍃 𐌾𐌰𐌷 𐌽𐌹 𐌼𐌰𐌲 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌳𐌰.",
        "tooltip-ca-nstab-project": "𐌰𐍄𐌰𐌿𐌲𐌴𐌹 𐍆𐌰𐌿𐍂𐌰𐍅𐌰𐌿𐍂𐍀𐌰𐌻𐌰𐌿𐍆",
-       "tooltip-ca-nstab-image": "𐍃𐌰𐌹𐍈𐌰𐌽 𐌸𐍉 𐍆𐌴𐌹𐌻𐌰𐍃𐌴𐌹𐌳𐍉𐌽",
+       "tooltip-ca-nstab-image": "𐍃𐌰𐌹𐍈 𐍆𐌰𐌴𐌹𐌻𐌰𐌻𐌰𐌿𐍆",
        "tooltip-ca-nstab-template": "𐍃𐌰𐌹𐍈𐌹𐍃 𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽",
        "tooltip-ca-nstab-category": "𐍃𐌰𐌹𐍈 𐌺𐌿𐌽𐌾𐌰𐌻𐌰𐌿𐍆",
        "tooltip-save": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌸𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃",
        "tooltip-preview": "𐍆𐌰𐌿𐍂𐍃𐌰𐍈𐌹𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌴𐌹𐌽𐍉𐍃 𐌸𐌴𐌹𐌽𐌰, 𐌱𐌹𐌳𐌾𐌰 𐌸𐌿𐌺 𐌱𐍂𐌿𐌺𐌾𐌰𐌽 𐌸𐌰𐍄𐌰 𐍆𐌰𐌿𐍂𐌰 𐌼𐌴𐌻𐌾𐌹𐍃!",
        "tooltip-diff": "𐌰𐍄𐌰𐌿𐌲𐌴𐌹 𐍈𐌹𐌻𐌴𐌹𐌺𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃 𐌲𐌰𐍄𐌰𐍅𐌹𐌳𐌴𐍃 𐌳𐌿 𐌸𐌰𐌹𐌼 𐌱𐍉𐌺𐍉𐌼",
-       "tooltip-rollback": "\"ð\90\8c°ð\90\8d\86ð\90\8d\85ð\90\8c°ð\90\8c»ð\90\8d\85ð\90\8c¾ð\90\8c°ð\90\8c½\" ð\90\8c±ð\90\8c°ð\90\8cºð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c³ð\90\8c¾ð\90\8c¹ð\90\8c¸ ð\90\8c¹ð\90\8c½ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c³ð\90\8c¾ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8d\83 ð\90\8c±ð\90\8c¹ ð\90\8c¸ð\90\8c¹ð\90\8c¶ð\90\8c°ð\90\8c¹ ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89ð\90\8c½ ð\90\8d\85ð\90\8c¹ð\90\8d\83ð\90\8c°ð\90\8c½ ð\90\8d\83ð\90\8d\89 ð\90\8c²ð\90\8c°ð\90\8c¼ð\90\8c°ð\90\8c³ð\90\8c¾ð\90\8c´ð\90\8c¹ ð\90\8c¼ð\90\8c°ð\90\8c½ð\90\8c°ð\90\8c²ð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8d\83 ð\90\8c½ð\90\8c¹ð\90\8c¿ð\90\8c¾ð\90\8c° ð\90\8c²ð\90\8c¹ð\90\8c±ð\90\8c°ð\90\8c¾ð\90\8c¹ð\90\8c½ð\90\8d\83 ð\90\8d\86ð\90\8d\82ð\90\8c°ð\90\8c¼ ð\90\8c°ð\90\8c¹ð\90\8c½ð\90\8d\83 ð\90\8cºð\90\8c»ð\90\8c¹ð\90\8cº",
+       "tooltip-rollback": "\"ð\90\8c°ð\90\8d\86ð\90\8d\85ð\90\8c°ð\90\8c»ð\90\8d\85ð\90\8c´ð\90\8c¹\" ð\90\8c²ð\90\8c°ð\90\8c½ð\90\8c°ð\90\8d\83ð\90\8c¾ð\90\8c¹ð\90\8c¸ ð\90\8c¹ð\90\8c½ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c³ð\90\8c´ð\90\8c¹ð\90\8c½(ð\90\8d\89ð\90\8d\83) ð\90\8c³ð\90\8c¿ ð\90\8c¸ð\90\8c°ð\90\8c¼ð\90\8c¼ð\90\8c° ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8c±ð\90\8c° ð\90\8c°ð\90\8d\86ð\90\8d\84ð\90\8c¿ð\90\8c¼ð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8c¹ð\90\8d\83 ð\90\8c±ð\90\8c¹ð\90\8c°ð\90\8c¿ð\90\8cºð\90\8c°ð\90\8c½ð\90\8c³ð\90\8c¹ð\90\8d\83\90\8c°ð\90\8d\86ð\90\8d\84ð\90\8c¿ð\90\8c¼ð\90\8c¹ð\90\8d\83ð\90\8d\84ð\90\8c°ð\90\8c¹ð\90\8c¶ð\90\8d\89ð\90\8d\83 ð\90\8c±ð\90\8c¹ð\90\8c°ð\90\8c¿ð\90\8cºð\90\8c°ð\90\8c½ð\90\8c³ð\90\8c¾ð\90\8d\89ð\90\8d\83 ð\90\8c¹ð\90\8c½ ð\90\8c°ð\90\8c¹ð\90\8c½ð\90\8c°ð\90\8c¼ð\90\8c¼ð\90\8c° ð\90\8d\83ð\90\8c¹ð\90\8c½ð\90\8c¸ð\90\8c°",
        "tooltip-undo": "\"𐌽𐌹𐌿𐍃𐌺𐌰𐍀𐌾𐌰𐌽\" 𐌱𐌰𐌺𐌼𐌰𐌹𐌳𐌾𐌹𐌸 𐌹𐌽𐌼𐌰𐌹𐌳𐌲𐌴𐌹𐌽𐍃 𐌾𐌰𐌷 𐌿𐍃𐌻𐌿𐌺𐍉𐌸 𐌼𐌰𐌹𐌳𐌾𐌰𐍆𐍉𐍂𐌼𐍉𐌽 𐍃𐍅𐌴 𐍆𐌰𐌿𐍂𐍃𐌰𐌹𐍈𐌰 𐌷𐌹𐍅𐌾𐌰. 𐌸𐌰𐍄𐌰 𐌻𐌴𐍄 𐌰𐌽𐌰𐌿𐌺𐌰𐌽𐌰𐌽 𐍃𐌰𐌿𐌸𐌰 𐌹𐌽 𐌹𐌽𐌽𐌰𐌷𐌰𐌻𐌳𐌰𐌰𐌽𐌲𐌰𐌱𐌰.",
        "tooltip-summary": "𐌰𐍄𐌲𐌰𐌲𐌲𐌹𐍃 𐌹𐌽𐌽𐌰𐌷𐌰𐌻𐌳𐌰𐌰𐌽𐌲𐌰𐌱𐌰 𐌼𐌰𐌿𐍂𐌲𐌾𐌰",
        "pageinfo-toolboxlink": "𐌺𐌿𐌽𐌸𐌹 𐌻𐌰𐌿𐌱𐌹𐍃",
index c7d7099..f1cf530 100644 (file)
@@ -28,7 +28,7 @@
        "tog-showtoolbar": "Chán-sṳ phiên-siá kûng-khí-làn",
        "tog-editondblclick": "Sûng-khim phiên-siá ya̍p-mien",
        "tog-editsectiononrightclick": "Yún-hí yu-khim phiêu-thì phiên-siá thon-lo̍k",
-       "tog-watchcreations": "Kâ ngài kien-li̍p ke ya̍p-mien lâu sông-chhòn ke vùn-khien kâ-ngi̍p ngài-ke kâm-sṳ lie̍t-péu",
+       "tog-watchcreations": "Kâ ngài kien-li̍p ke ya̍p-mien lâu sông-chhòn ke tóng-on kâ-ngi̍p ngài-ke kâm-sṳ lie̍t-péu",
        "tog-watchdefault": "Chiông ngài phiên-siá ke ya̍p-mien lâu tóng-on kâ-ngi̍p ngài-ke kâm-sṳ lie̍t-péu",
        "tog-watchmoves": "Chiông ngài yì-thûng ke ya̍p-mien lâu tóng-on kâ-ngi̍p ngài-ke kâm-sṳ lie̍t-péu",
        "tog-watchdeletion": "加亻厓刪除嘅頁面撈文件入亻厓嘅監視列表",
        "edit": "Phiên-siá",
        "create": "Kien-li̍p",
        "create-local": "Sîn-chen pún-thi sot-mìn",
-       "editthispage": "Phiên-siá pún-ya̍p",
+       "editthispage": "Phiên-siá liá ya̍p",
        "create-this-page": "Kien-li̍p pún-ya̍p",
        "delete": "San-chhù",
        "deletethispage": "San-chhù pún-ya̍p",
        "talkpagelinktext": "kâu-liù",
        "specialpage": "Thi̍t-sû ya̍p-mien",
        "personaltools": "Sṳ̂-ngìn kûng-khí",
-       "articlepage": "Chhà-khon nui-yùng ya̍p-mien",
+       "articlepage": "Khon nui-yùng ya̍p",
        "talk": "Thó-lun",
        "views": "Chhà-khon-sú",
        "toolbox": "Kûng-khí-siông",
        "youhavenewmessagesmulti": "Ngì chhai $1-tú yû sîn sêu-sit",
        "editsection": "phiên-siá",
        "editold": "phiên-siá",
-       "viewsourceold": "chhà-khon ngièn-ma",
+       "viewsourceold": "Khon ngièn-sṳ́-mâ",
        "editlink": "phiên-siá",
-       "viewsourcelink": "chhà-khon ngièn-ma",
+       "viewsourcelink": "Khon ngièn-sṳ́-mâ",
        "editsectionhint": "Phiên-siá chông-chiet: $1",
        "toc": "Muk-liu̍k",
        "showtoc": "Chán-sṳ",
        "perfcached": "下列係緩存數據,因此可能毋係最新嘅。最多{{PLURAL:$1|單淨有1嘅結果|$1嘅結果}}可用。",
        "perfcachedts": "下列係緩存數據,其最後更新時間係$1。單淨有{{PLURAL:$4|一嘅結果|$4嘅結果}}會畀顯示。",
        "querypage-no-updates": "當前禁止對邇頁面進行更新。\n邇位嘅數據將做毋得分立即重新整理。",
-       "viewsource": "Chhà-khon ngièn-ma",
-       "viewsource-title": "查看$1嘅源代碼",
+       "viewsource": "Khon ngièn-sṳ́-mâ",
+       "viewsource-title": "Khon $1 ke ngièn-sṳ́-mâ",
        "actionthrottled": "動作已經壓制",
        "actionthrottledtext": "基於反垃圾嘅考量,短時間內毋可以多次重複某操作,今下汝已經超過邇隻上限。\n請在數分鐘後再嘗試。",
        "protectedpagetext": "邇隻頁面已經分人保護以防止編輯或其他操作。",
        "group-bureaucrat-member": "行政員",
        "grouppage-bot": "{{ns:project}}:機器人",
        "grouppage-sysop": "{{ns:project}}:管理員",
-       "right-upload": "Sông-chhòn vùn-khien",
+       "right-upload": "Sông-chhòn tóng-on",
        "right-writeapi": "Sṳ́-yung siá-ngi̍p API",
        "newuserlogpage": "Sîn-kien yung-fu miàng-chhak",
        "newuserlogpagetext": "邇係一隻最近人創建用戶嘅新日誌",
        "recentchanges-legend": "Chui-khiûn kiên-kói sién-hong",
        "recentchanges-summary": "Kiên-chiûng pún wiki sông ke chui-sîn kiên-kói.",
        "recentchanges-feed-description": "Kiên-chiûng pún thin-ye̍t chhai wiki sông ke chui-khiûn kiên-kói.",
-       "recentchanges-label-newpage": "Liá-chhṳ phiên-si̍p kien-li̍p hí yit-chak sîn ya̍p-mien",
+       "recentchanges-label-newpage": "Liá-ke phiên-siá kien-li̍p sîn ya̍p",
        "recentchanges-label-minor": "Liá-he yit-chak se-mì siû-kói",
        "recentchanges-label-bot": "Liá-chhṳ phiên-siá he yù kî-hi-ngìn chin-hàng",
        "recentchanges-label-unpatrolled": "Liá-chhṳ phiên-siá hàn-mò sùn-chhà ko",
        "recentchanges-label-plusminus": "Kâi ya̍p-mien kiên-kói ke thai-séu  (vi-ngièn-chû)",
        "recentchanges-legend-heading": "<strong>Chu-yi:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (chhiáng chhâm-siòng [[Special:NewPages|sîn ya̍p-mien]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (chhâm-siòng [[Special:NewPages|sîn ya̍p]])",
        "rcnotefrom": "下背係從'''$2'''起嘅更改(最多展示'''$1'''):",
        "rclistfrom": "Chán-sṳ chhiùng $3 $2 yî-lòi ke sîn kiên-kói",
        "rcshowhideminor": "$1細微編寫",
        "recentchangeslinked-summary": "邇一隻特殊頁面列示''由''所分出嘅一隻頁面之鏈接到頁面嘅最近更改(或者是對於指定分類嘅成員)。\n在[[Special:Watchlist|汝嘅監視列表]]肚嘅頁面會用'''粗體'''顯示。",
        "recentchangeslinked-page": "Ya̍p-mien miàng:",
        "recentchangeslinked-to": "Chán-sṳ lièn-to só fûn-chhut ke ya̍p-mien",
-       "upload": "Sông-chhòn vùn-khien",
-       "uploadbtn": "Sông-chhòn vùn-khien",
+       "upload": "Sông-chhòn tóng-on",
+       "uploadbtn": "Sông-chhòn tóng-on",
        "reuploaddesc": "取消上載並返回上載表單",
        "uploadnologin": "還吂登入",
        "uploadnologintext": "汝必須先[[Special:UserLogin|登入]]\n正做得上傳文件。",
        "uploaderror": "上傳差錯",
        "uploadtext": "Sṳ́-yung ha-mien ke péu-tân lòi song-chhòn yung-chhai vùn-chông nui sîn-ke thù-hìn tóng-on. Yeu kiám-sṳ fe̍t-chá sêu-chhà yî-chhièn song-chhòn ke thù-phién khó-yî chin-ngi̍p [[Special:FileList|Thù-hìn chhîn-tân]], song-chhòn lâu chhù-hi chiông-chhai [[Special:Log/upload|Song-chhòn ngit-ki]] chûng ki-liu̍k. Yeu-chhai vùn-chông chûng kâ-ngi̍p thù-hiong, sṳ́-yung yî-ha hìn-sṳt ke lièn-chiap: '''<nowiki>[[{{ns:file}}:file.jpg]]</nowiki>''', '''<nowiki>[[{{ns:file}}:file.png|Thi-von vùn-sṳ]]</nowiki>''' fe̍t-he '''<nowiki>[[{{ns:media}}:file.ogg]]</nowiki>'''.",
        "uploadlogpage": "上傳日誌",
-       "uploadlogpagetext": "Yî-ha he chui-khiûn song-chhòn vùn-khien ke chúng-péu.",
+       "uploadlogpagetext": "Yî-ha he chui-khiûn sông-chhòn tóng-on ke chúng-péu.",
        "filename": "文件名",
        "filedesc": "Vùn-khien sot-mìn",
        "fileuploadsummary": "文件摘要:",
        "pager-older-n": "khiu $1-chhṳ",
        "booksources": "Mióng-lok sû-ngièn",
        "booksources-search-legend": "Chhìm-cháu mióng-lok sû-ngièn",
-       "booksources-search": "Chhìm-cháu",
+       "booksources-search": "Chhìm",
        "booksources-text": "下背係一份銷售新書或二手書嘅列表,並可能有汝尋找緊嘅書嘅進一步信息:",
        "specialloguserlabel": "Yung-fu:",
        "speciallogtitlelabel": "Phêu-thì:",
        "sp-contributions-username": "IP地址或用戶名:",
        "sp-contributions-toponly": "單淨展示最新修訂版本嘅編寫",
        "sp-contributions-submit": "搜尋",
-       "whatlinkshere": "Lièn-chiap ngi̍p ya̍p-mien",
+       "whatlinkshere": "Nâi-têu lièn to liá-têu",
        "whatlinkshere-title": "Lièn-chiap to \"$1\" ke ya̍p-mien",
        "whatlinkshere-page": "Ya̍p-mien:",
        "linkshere": "Hâ-poi ya̍p-mien lièn-chiap to <strong>[[:$1]]</strong>:",
        "tooltip-pt-mycontris": "{{GENDER:|Ngì ke}} kung-hien lie̍t-péu",
        "tooltip-pt-login": "Kien-ngi ngì tên-ngi̍p, than-he pin fî pit-sî ke",
        "tooltip-pt-logout": "Tên-chhut",
-       "tooltip-ca-talk": "Kôan-yî ya̍p-mien chang-vùn ke thó-lun",
+       "tooltip-ca-talk": "Liá ya̍p ke thó-lun",
        "tooltip-ca-edit": "Phiên-siá pún-ya̍p",
        "tooltip-ca-addsection": "Khôi-sṳ́ yit-chak sîn thon-lo̍k",
-       "tooltip-ca-viewsource": "Pún ya̍p-mien su-to pó-fu. \nNgì cho-tet chhà-khon khì ke ngièn-ma.",
-       "tooltip-ca-history": "Pún ya̍p-mien chó-siên ke siû-thin pán-pún",
+       "tooltip-ca-viewsource": "Liá-ke ya̍p-mien su-to pó-fu. \nNgì cho-tet khon khì ke ngièn-sṳ́-mâ.",
+       "tooltip-ca-history": "Liá ya̍p chó-siên ke pán-pún",
        "tooltip-ca-protect": "保護邇頁",
        "tooltip-ca-delete": "刪除邇頁",
        "tooltip-ca-undelete": "Chiông liá-ke vùn-chông fî-fu̍k to pûn chhù-hi yî-chhièn ke chhong-khóng",
        "tooltip-feed-atom": "Thin-ye̍t liá-ya̍p ke Atom ngièn",
        "tooltip-t-contributions": "Chhà-khon {{GENDER:$1|liá-chak yung-fu}} ke kung-hien lie̍t-péu",
        "tooltip-t-emailuser": "向邇隻用戶發送電子郵件",
-       "tooltip-t-upload": "Sông-chhòn vùn-khien",
+       "tooltip-t-upload": "Sông-chhòn tóng-on",
        "tooltip-t-specialpages": "Chhiòn-phu thi̍t-sû vùn-chông ke lie̍t-péu",
        "tooltip-t-print": "Pún ya̍p-mien cho-tet tá-yin ke pán-pún",
        "tooltip-t-permalink": "Liá-chak ya̍p-mien pán-pún ke ku-thin lièn-kiet",
-       "tooltip-ca-nstab-main": "Chhà-khon nui-yùng ya̍p",
+       "tooltip-ca-nstab-main": "Khon nui-yùng ya̍p",
        "tooltip-ca-nstab-user": "Chhà-khon yung-fu ya̍p-mien",
        "tooltip-ca-nstab-media": "Chhà-khon hìn-thí-chông",
        "tooltip-ca-nstab-special": "Pún ya̍p-mien he thi̍t-sû ya̍p-mien, ngì cho-m̀-tet phiên-siá pún-ya̍p",
        "newimages": "Sîn-kien thù-chhiong ke va̍k-lòng",
        "imagelisttext": "Yî-ha he on $2 phài-lie̍t ke $1-ke tóng-on lie̍t-péu.",
        "noimages": "Mò-khó kiám-sṳ thù-chhiong.",
-       "ilsubmit": "Chhìm-cháu",
+       "ilsubmit": "Chhìm",
        "bydate": "on-cheu ngit-khì",
        "sp-newimages-showfrom": "Chhiùng $1 khôi-sṳ́ hién-sṳ sîn thù-phién",
        "bad_image_list": "請按照下列格式編寫:\n\n單淨係有(以*開頭)列出嘅項目會分考慮。\n每一行嘅第一條鏈接必須係損壞文件嘅鏈接。\n然後同一行後方嘅鏈接會分看做例外,也就係講邇文件做得在哪兜頁面肚分顯示。",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|kâu-liù]])",
        "duplicate-defaultsort": "'''警告:'''默認排序關鍵字“$2”蓋過矣先前嘅默認排序關鍵字“$1”。",
        "version": "Pán-pún",
-       "fileduplicatesearch-submit": "Chhìm-cháu",
+       "fileduplicatesearch-submit": "Chhìm",
        "specialpages": "Thi̍t-sû ya̍p",
        "external_image_whitelist": " #留下撈邇行一樣嘅文字<pre>\n#在下背(//中間部份)輸入正則表達式\n#邇兜將會撈外部(已超鏈接嘅)圖片配合\n#遐兜配合上嘅會顯示成圖片,否則就單淨會顯示成鏈接\n#有#開頭嘅行會當成意見\n#大小寫並無區分\n\n#在邇行上片輸入全部正則表達式。留下撈邇行一樣嘅文字</pre>",
        "tag-filter": "[[Special:Tags|Phiêu-chhiam]] ko-lì-hi:",
        "logentry-upload-upload": "$1 {{GENDER:$2|yí-kîn sông-chhòn}} $3",
        "rightsnone": "(無)",
        "revdelete-summary": "piên-sip tsak-yêu",
-       "searchsuggest-search": "Chhìm-cháu"
+       "searchsuggest-search": "Chhìm"
 }
index 0c3dcbf..7e94b9c 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "אוביקט ריק",
        "content-json-empty-array": "מערך ריק",
+       "deprecated-self-close-category": "דפים שמשתמשים בתגיות HTML עם סגירה עצמית בלתי חוקית",
+       "deprecated-self-close-category-desc": "דף זה כולל תגיות HTML עם סגירה עצמית בלתי חוקית, כגון <code dir=\"ltr\">&lt;b/></code> או <code dir=\"ltr\">&lt;span/></code>. ההתנהגות של תגיות אלה תשתנה בקרוב לצורך תאימות עם מפרט HTML5, ולכן יש להימנע משימוש בהן בקוד ויקי.",
        "duplicate-args-warning": "<strong>אזהרה:</strong> [[:$1]] קורא לדף [[:$2]] עם יותר מערך אחד עבור הפרמטר \"$3\". ייעשה שימוש רק בערך האחרון.",
        "duplicate-args-category": "דפים שמשתמשים בפרמטרים כפולים בקריאות לתבניות",
        "duplicate-args-category-desc": "הדף מכיל קריאות לתבניות שמשתמשות בפרמטרים כפולים, כגון <code><nowiki>{{תאריך|יום=1|יום=2}}</nowiki></code> או <code><nowiki>{{שעה|חמש|1=שש}}</nowiki></code>.",
        "last": "קודמת",
        "page_first": "ראשון",
        "page_last": "אחרון",
-       "histlegend": "בחירת גרסאות להשוואה: סמנו את תיבות האפשרויות של הגרסאות המיועדות להשוואה, והקישו על Enter או על הכפתור למטה.<br />\nמקרא: '''({{int:cur}})''' = השוואה עם הגרסה הנוכחית, '''({{int:last}})''' = השוואה עם הגרסה הקודמת, '''{{int:minoreditletter}}''' = שינוי משני.",
+       "histlegend": "בחירת גרסאות להשוואה: {{GENDER:|בחר|בחרי|בחרו}} את הגרסאות ש{{GENDER:|ברצונך|ברצונך|ברצונכם}} להשוות ולאחר מכן {{GENDER:|הקש|הקישי|הקישו}} על Enter או {{GENDER:|לחץ|לחצי|לחצו}} על הכפתור שלמטה.<br />\nמקרא: <strong>({{int:cur}})</strong> = השוואה עם הגרסה הנוכחית, <strong>({{int:last}})</strong> = השוואה עם הגרסה הקודמת, <strong>{{int:minoreditletter}}</strong> = עריכה משנית.",
        "history-fieldset-title": "חיפוש בהיסטוריית הדף",
        "history-show-deleted": "עריכות מוסתרות בלבד",
        "histfirst": "הישנות ביותר",
        "autoblockid": "חסימה אוטומטית #$1",
        "block": "חסימת משתמש",
        "unblock": "שחרור חסימה של משתמש",
-       "blockip": "חסימת {{GENDER:$1|משתמש|משתמשת}}",
+       "blockip": "חסימת ה{{GENDER:$1|משתמש|משתמשת}}",
        "blockip-legend": "חסימת משתמש",
        "blockiptext": "השתמשו בטופס שלהלן כדי לחסום את הרשאות הכתיבה מכתובת IP או משתמש מסוימים.\nחסימות כאלה צריכות להתבצע רק כדי למנוע השחתה, ובהתאם ל[[{{MediaWiki:Policy-url}}|נהלים]].\nאנא מלאו את הסיבה הפרטנית לחסימה להלן (לדוגמה, באמצעות ציון דפים מסוימים שהשחית המשתמש).\nבאפשרותכם לחסום טווחי כתובות IP באמצעות תחביר [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; הטווח הגדול ביותר שניתן לחסום הוא <span dir=\"ltr\">/$1</span> עבור IPv4 ו־<span dir=\"ltr\">/$2</span> עבור IPv6.",
        "ipaddressorusername": "כתובת IP או שם משתמש:",
        "move-watch": "מעקב אחרי דף המקור ואחרי דף היעד",
        "movepagebtn": "העברת הדף",
        "pagemovedsub": "ההעברה הושלמה בהצלחה",
-       "movepage-moved": "הדף \"$1\" הועבר לשם \"$2\".",
+       "movepage-moved": "<strong>הדף \"$1\" הועבר לשם \"$2\"</strong>",
        "movepage-moved-redirect": "נוצרה הפניה.",
        "movepage-moved-noredirect": "יצירת ההפניה בוטלה.",
        "articleexists": "קיים כבר דף באותו שם, או שהשם שבחרת אינו תקין.\nנא לבחור שם אחר.",
        "mw-widgets-dateinput-no-date": "לא נבחר תאריך",
        "mw-widgets-titleinput-description-new-page": "הדף עדיין לא קיים",
        "mw-widgets-titleinput-description-redirect": "הפניה ל{{GRAMMAR:תחילית|$1}}",
-       "api-error-blacklisted": "נא לבחור כותרת אחרת, המתארת טוב יותר את התוכן.",
        "sessionmanager-tie": "לא ניתן לצרף מספר סוגי אימות זהות: $1.",
        "sessionprovider-generic": "התחברויות של $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "התחברויות המבוססות על עוגיות",
index eb64a27..fd7476b 100644 (file)
                        "Srdjan m",
                        "Teoo3",
                        "Matma Rex",
-                       "Vrhnje"
+                       "Vrhnje",
+                       "Ivi104"
                ]
        },
-       "tog-underline": "Podcrtane poveznice",
+       "tog-underline": "Podcrtavanje poveznica",
        "tog-hideminor": "Sakrij manje izmjene u nedavnim promjenama",
        "tog-hidepatrolled": "Sakrij pregledane izmjene u nedavnim promjenama",
        "tog-newpageshidepatrolled": "Sakrij pregledane stranice iz popisa novih stranica",
@@ -76,7 +77,7 @@
        "tog-ccmeonemails": "Pošalji mi kopiju e-maila kojeg pošaljem drugim suradnicima",
        "tog-diffonly": "Ne prikazuj sadržaj stranice prilikom usporedbe inačica",
        "tog-showhiddencats": "Prikaži skrivene kategorije",
-       "tog-norollbackdiff": "Izostavi razliku nakon upotrebe ukloni",
+       "tog-norollbackdiff": "Izostavi razliku nakon vraćanja",
        "tog-useeditwarning": "Upozori me kad napuštam stranicu za uređivanje bez spremanja izmjena",
        "tog-prefershttps": "Uvijek koristi sigurnu vezu kod prijave",
        "underline-always": "Uvijek",
        "readonly_lag": "Baza podataka je automatski zaključana dok se sekundarni bazni poslužitelji ne usklade s glavnim",
        "internalerror": "Pogreška sustava",
        "internalerror_info": "Interna pogrješka: $1",
+       "internalerror-fatal-exception": "Terminalna pogreška \"$1\"",
        "filecopyerror": "Ne mogu kopirati datoteku \"$1\" u \"$2\".",
        "filerenameerror": "Ne mogu preimenovati datoteku \"$1\" u \"$2\".",
        "filedeleteerror": "Ne mogu obrisati datoteku \"$1\".",
        "cannotdelete": "Ne može se obrisati stranica ili datoteka \"$1\".\nMoguće je da ju je netko drugi već obrisao.",
        "cannotdelete-title": "Brisanje stranice \"$1\" nije moguće",
        "delete-hook-aborted": "Brisanje prekinuto softverskim priključkom (hook).\nNema obrazloženja ili poruke o pogrješci.",
+       "no-null-revision": "Ne mogu stvoriti praznu izmjenu stranice \"$1\"",
        "badtitle": "Loš naslov",
        "badtitletext": "Navedeni naslov stranice nepravilan ili loše formirana interwiki poveznica.",
        "title-invalid-empty": "Naslov tražene stranice je prazan ili sadrži samo naziv prostora imena.",
        "title-invalid-interwiki": "Traženi naziv stranice sadrži interwiki poveznicu koja se ne može koristiti u nazivima.",
        "title-invalid-talk-namespace": "Traženi naziv stranice odnosi se na stranicu rasprave koja ne može postojati.",
        "title-invalid-characters": "Traženi naziv stranice sadrži nevažeće znakove: \"$1\"",
+       "title-invalid-relative": "Naslov ima relativan put. Relativni putovi u naslovu su nevažeći, jer ih web pretraživač često ne može doseći.",
+       "title-invalid-too-long": "Naslov stranice je predugačak. Naslov ne smije biti duži od $1 {{PLURAL:$1|bajt|bajtova}} u UTF-8 kodiranju.",
        "perfcached": "Sljedeći podaci su iz međuspremnika i možda nisu najsvježiji. Međuspremnik sadrži $1 {{PLURAL:$1|rezultat|rezultata}} pretraživanja.",
        "perfcachedts": "Sljedeći podaci su iz međuspremnika i posljednji puta su ažurirani u $1. Međuspremnik sadrži $4 {{PLURAL:$4|rezultat|rezultata}} pretraživanja.",
        "querypage-no-updates": "Osvježavanje ove stranice je trenutačno onemogućeno. Nove promjene neće biti vidljive.",
        "viewsource": "Vidi izvornik",
        "viewsource-title": "Vidi kôd stranice $1",
        "actionthrottled": "Uređivanje je usporeno",
-       "actionthrottledtext": "Kao anti-spam mjeru, ograničeni ste u broju ovih radnji u određenom vremenu, i trenutačno ste dosegli to ograničenje. Pokušajte opet za koju minutu.",
+       "actionthrottledtext": "Kao mjera protiv spama, ograničeni vam je broj ovih radnji u određenom vremenu, i trenutačno ste dostigli to ograničenje. Pokušajte opet za par minuta.",
        "protectedpagetext": "Ova stranica je zaključana da bi se onemogućile izmjene.",
        "viewsourcetext": "Možete pogledati i kopirati izvorni sadržaj ove stranice.",
        "viewyourtext": "Možete vidjeti i kopirati tekst <strong>vaših uređivanja</strong> na ovoj stranici.",
        "password-change-forbidden": "Ne možete promjeniti zaporku na ovom projektu.",
        "externaldberror": "Došlo je do pogreške s vanjskom autorizacijom ili Vam nije dopušteno osvježavanje vanjskog suradničkog računa.",
        "login": "Prijavi se",
+       "login-security": "Potvrdite svoj identitet",
        "nav-login-createaccount": "Prijavi se",
        "userlogin": "Prijavi se / stvori račun",
        "userloginnocreate": "Prijavi se",
        "saveusergroups": "Snimi suradničke skupine",
        "userrights-groupsmember": "Član:",
        "userrights-groupsmember-auto": "Uključeni član:",
-       "userrights-groups-help": "Možete promijeniti skupine za ovog suradnika:\n* Označena kućica pokazuje skupinu kojoj suradnik pripada.\n* Neoznačena kućica pokazuje skupinu kojoj suradnik ne pripada.\n* Zvjezdica * označava skupinu koju ne možete ukloniti kad ju jednom dodate, ili obratno.",
+       "userrights-groups-help": "Možete promijeniti skupine za ovog suradnika:\n* označena kućica pokazuje skupinu kojoj suradnik pripada;\n* neoznačena kućica pokazuje skupinu kojoj suradnik ne pripada;\n* zvjezdica (*) označava skupinu koju ne možete ukloniti kad ju jednom dodate, ili obratno.",
        "userrights-reason": "Razlog:",
        "userrights-no-interwiki": "Nemate dopuštenje za uređivanje suradničkih prava na drugim wikijima.",
        "userrights-nodatabase": "Baza podataka $1 ne postoji ili nije lokalno dostupna.",
        "unusedimages": "Nekorištene slike",
        "wantedcategories": "Tražene kategorije",
        "wantedpages": "Tražene stranice",
+       "wantedpages-summary": "Niže je popis nepostojećih stranica s najviše poveznica prema njima, osim stranica koje imaju preusmjeravanje na njih. Cijeli popis nepostojećih stranica na koje postoje preusmjeravanja može se vidjeti na [[{{#special:BrokenRedirects}}|popisu]].",
        "wantedpages-badtitle": "Nevaljani naslov kao rezultat: $1",
        "wantedfiles": "Tražene datoteke",
        "wantedfiletext-cat": "Sljedeće datoteke se rabe ali ne postoje. Datoteke iz drugih izvora mogu biti navedene iako ne postoje. Takve datoteke će biti <del>izbrisane</del> s popisa. Osim toga, stranice koje sadrže nepostojeće datoteke popisane su [[:$1|ovdje]].",
        "sp-contributions-username": "IP adresa ili suradnik:",
        "sp-contributions-toponly": "Prikaži samo najnovije izmjene",
        "sp-contributions-newonly": "Pokaži samo stranice koje je suradnik započeo",
+       "sp-contributions-hideminor": "Sakrij manje izmjene",
        "sp-contributions-submit": "Traži",
        "whatlinkshere": "Što vodi ovamo",
        "whatlinkshere-title": "Stranice koje vode na \"$1\"",
        "mw-widgets-dateinput-placeholder-month": "GGGG-MM",
        "mw-widgets-titleinput-description-new-page": "stranica još ne postoji",
        "mw-widgets-titleinput-description-redirect": "preusmjeravanje na $1",
+       "log-action-filter-newusers": "Način stvaranja računa:",
        "log-action-filter-upload": "Vrsta postavljanja:",
        "log-action-filter-all": "sve",
+       "log-action-filter-newusers-create": "stvorio anonimni suradnik",
+       "log-action-filter-newusers-create2": "stvorio registrirani suradnik",
+       "log-action-filter-newusers-autocreate": "automatski stvoren",
+       "log-action-filter-newusers-byemail": "stvoren lozinkom poslanom na e-poštu",
        "log-action-filter-upload-upload": "novo postavljanje",
        "log-action-filter-upload-overwrite": "ponovno postavljanje"
 }
index 1a51e60..2bbaebe 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Üres objektum",
        "content-json-empty-array": "Üres tömb",
+       "deprecated-self-close-category": "Érvénytelen önzáró HTML-címkéket használó lapok",
        "duplicate-args-warning": "<strong>Figyelmeztetés:</strong> A(z) [[:$1]] lap dupla értékkel hívja meg a(z) [[:$2]] sablont („$3” paraméter). Csak az utolsó érték lesz felhasználva.",
        "duplicate-args-category": "Dupla paramétermegadást tartalmazó lapok",
        "duplicate-args-category-desc": "Az oldal olyan sablon hívásokat tartalmaz, amely ugyanazt a paramétert használja, például <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "ÉÉÉÉ-HH",
        "mw-widgets-titleinput-description-new-page": "a lap még nem létezik",
        "mw-widgets-titleinput-description-redirect": "átirányítás ide: $1",
-       "api-error-blacklisted": "Válasszon egy másik, leíró címet.",
        "sessionprovider-generic": "$1-munkamenetek",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sütialapú munkamenetek",
        "sessionprovider-nocookies": "A sütik le lehetnek tiltva. Engedélyezd a sütiket, és próbáld meg újra!",
index 655058d..2920310 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Objecto vacue",
        "content-json-empty-array": "Array vacue",
+       "deprecated-self-close-category": "Paginas que usa etiquettas HTML auto-claudite non valide",
+       "deprecated-self-close-category-desc": "Le pagina contine etiquettas HTML auto-claudite non valide, como <code>&lt;b/></code> o <code>&lt;span/></code>. Le comportamento de istes cambiara proximemente pro esser in accordo con le specification HTML5, dunque lor uso in wikitexto es obsolete.",
        "duplicate-args-warning": "<strong>Attention:</strong> [[:$1]] appella [[:$2]] con plure valores pro le parametro \"$3\". Solmente le ultime valor fornite essera usate.",
        "duplicate-args-category": "Paginas que usa parametros duplicate in appellos de patrono",
        "duplicate-args-category-desc": "Le pagina contine appellos de patrono que usa duplicatos de parametros, como per exemplo <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "pagina non existe ancora",
        "mw-widgets-titleinput-description-redirect": "redirection a $1",
-       "api-error-blacklisted": "Per favor elige un altere titulo, plus descriptive.",
        "sessionmanager-tie": "Impossibile combinar plure typos de authentication de requesta: $1.",
        "sessionprovider-generic": "sessiones $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessiones basate sur cookies",
        "log-action-filter-newusers": "Typo de creation de conto:",
        "log-action-filter-patrol": "Typo de patrulia:",
        "log-action-filter-protect": "Typo de protection:",
-       "log-action-filter-rights": "Typo de cambio de derecto",
-       "log-action-filter-suppress": "Typo de suppression",
+       "log-action-filter-rights": "Typo de cambio de derecto:",
+       "log-action-filter-suppress": "Typo de suppression:",
        "log-action-filter-upload": "Typo de incargamento:",
        "log-action-filter-all": "Toto",
        "log-action-filter-block-block": "Blocar",
index 7a8e57a..8048a84 100644 (file)
        "rightslogtext": "Þetta er skrá yfir breytingar á réttindum notenda.",
        "action-read": "lesa þessa síðu",
        "action-edit": "breyta þessari síðu",
-       "action-createpage": "skapa síður",
-       "action-createtalk": "skapa spjallsíður",
+       "action-createpage": "skapa þessa síðu",
+       "action-createtalk": "skapa þessa spjallsíðu",
        "action-createaccount": "skapa þennan notandaaðgang",
        "action-autocreateaccount": "búa sjálfvirkt til þennan ytri notandaaðgang",
        "action-history": "skoða breytingaskrá þessarar síðu",
        "mw-widgets-dateinput-placeholder-month": "ÁÁÁÁ-MM",
        "mw-widgets-titleinput-description-new-page": "síðan er ekki enn til",
        "mw-widgets-titleinput-description-redirect": "tilvísun á $1",
-       "api-error-blacklisted": "Veldu annan lýsandi titil",
        "sessionmanager-tie": "Get ekki sameinað margar gerðir auðkenningarbeiðna: $1.",
        "sessionprovider-generic": "$1 setur",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "setur með vefkökum",
index 699bfbd..0ecc963 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Oggetto vuoto",
        "content-json-empty-array": "Array vuoto",
+       "deprecated-self-close-category": "Pagine che utilizzano tag HTML auto-chiusi non validi",
+       "deprecated-self-close-category-desc": "La pagina contiene tag HTML auto-chiusi non validi, come <code>&lt;b/></code> o <code>&lt;span/></code>. Il comportamento di questi presto cambierà per essere coerente con le specifiche HTML5, per questo il loro uso nel wikitesto è deprecato.",
        "duplicate-args-warning": "<strong>Avvertenza:</strong> [[:$1]] chiama [[:$2]] con più di un valore per il parametro \"$3\". Verrà utilizzato solo l'ultimo valore fornito.",
        "duplicate-args-category": "Pagine contenenti chiamate a template con parametri duplicati",
        "duplicate-args-category-desc": "La pagina contiene chiamate a template che utilizzano argomenti duplicati, come ad esempio <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> o <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "questa pagina non esiste ancora",
        "mw-widgets-titleinput-description-redirect": "reindirizzamento a $1",
-       "api-error-blacklisted": "Per favore scegli un titolo diverso e descrittivo.",
        "sessionmanager-tie": "Non è possibile combinare più tipi di richieste di autenticazione: $1.",
        "sessionprovider-generic": "sessioni $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessioni basate su cookie",
        "log-action-filter-newusers": "Tipo di creazione utenza:",
        "log-action-filter-patrol": "Tipo di verifica:",
        "log-action-filter-protect": "Tipo di protezione:",
-       "log-action-filter-rights": "Tipo di modifica diritti",
-       "log-action-filter-suppress": "Tipo di soppressione",
+       "log-action-filter-rights": "Tipo di modifica diritti:",
+       "log-action-filter-suppress": "Tipo di soppressione:",
        "log-action-filter-upload": "Tipo di caricamento:",
        "log-action-filter-all": "Tutto",
        "log-action-filter-block-block": "Blocco",
index 8e82375..fc76250 100644 (file)
        "sqlite-no-fts": "$1 (全文検索なし)",
        "logentry-delete-delete": "$1 がページ「$3」を{{GENDER:$2|削除しました}}",
        "logentry-delete-restore": "$1 がページ「$3」を{{GENDER:$2|復元しました}}",
-       "logentry-delete-event": "$1 が$3の{{PLURAL:$5|記録項目$5件}}の閲覧レベルを{{GENDER:$2|変更しました}}: $4",
-       "logentry-delete-revision": "$1 がページ「$3」の{{PLURAL:$5|$5版}}の閲覧レベルを{{GENDER:$2|変更しました}}: $4",
-       "logentry-delete-event-legacy": "$1 が「$3」の記録項目の閲覧レベルを{{GENDER:$2|変更しました}}",
+       "logentry-delete-event": "$1 が $3 の{{PLURAL:$5|記録項目|記録項目$5件}}の閲覧レベルを{{GENDER:$2|変更しました}}: $4",
+       "logentry-delete-revision": "$1 がページ「$3」の{{PLURAL:$5|版|$5件の版}}の閲覧レベルを{{GENDER:$2|変更しました}}: $4",
+       "logentry-delete-event-legacy": "$1 が $3 の記録項目の閲覧レベルを{{GENDER:$2|変更しました}}",
        "logentry-delete-revision-legacy": "$1 がページ「$3」の版の閲覧レベルを{{GENDER:$2|変更しました}}",
-       "logentry-suppress-delete": "$1 がページ「$3」を{{GENDER:$2|隠蔽しました}}",
-       "logentry-suppress-event": "$1 が$3の{{PLURAL:$5|記録項目$5件}}の閲覧レベルを見えない形で{{GENDER:$2|変更しました}}: $4",
-       "logentry-suppress-revision": "$1 がページ「$3」の{{PLURAL:$5|$5版}}の閲覧レベルを見えない形で{{GENDER:$2|変更しました}}: $4",
-       "logentry-suppress-event-legacy": "$1 が$3で記録項目の閲覧レベルを見えない形で{{GENDER:$2|変更しました}}",
+       "logentry-suppress-delete": "$1 がページ「$3」を{{GENDER:$2|秘匿しました}}",
+       "logentry-suppress-event": "$1 が $3 の{{PLURAL:$5|記録項目|$5件の記録項目}}の閲覧レベルを見えない形で{{GENDER:$2|変更しました}}: $4",
+       "logentry-suppress-revision": "$1 がページ「$3」の{{PLURAL:$5|版|$5件の版}}の閲覧レベルを見えない形で{{GENDER:$2|変更しました}}: $4",
+       "logentry-suppress-event-legacy": "$1 が $3 の記録項目の閲覧レベルを見えない形で{{GENDER:$2|変更しました}}",
        "logentry-suppress-revision-legacy": "$1 がページ「$3」の版の閲覧レベルを見えない形で{{GENDER:$2|変更しました}}",
        "revdelete-content-hid": "本文の不可視化",
        "revdelete-summary-hid": "編集要約の不可視化",
        "logentry-tag-update-add-logentry": "$1 がページ $3 の記録項目 $5 に{{PLURAL:$7|タグ}} $6 を{{GENDER:$2|追加しました}}",
        "logentry-tag-update-remove-revision": "$1 がページ $3 の版 $4 から{{PLURAL:$9|タグ}} $8 を{{GENDER:$2|除去しました}}",
        "logentry-tag-update-remove-logentry": "$1 がページ $3 の記録項目 $5 から{{PLURAL:$9|タグ}} $8 を{{GENDER:$2|除去しました}}",
-       "logentry-tag-update-revision": "$1 ã\81\8cã\83\9aã\83¼ã\82¸ã\80\8c$3ã\80\8dã\81®ç\89\88 $4 ã\81§ã\81®ã\82¿ã\82°ã\82\92{{GENDER:$2|æ\9b´æ\96°ã\81\97ã\81¾ã\81\97ã\81\9f}} ($6 ã\81\8c{{PLURAL:$7|追å\8a }}ã\80\81$8 ã\81\8c{{PLURAL:$9|削除}})",
+       "logentry-tag-update-revision": "$1 ã\81\8cã\83\9aã\83¼ã\82¸ã\80\8c$3ã\80\8dã\81®ç\89\88 $4 ã\81®ã\82¿ã\82°ã\82\92{{GENDER:$2|æ\9b´æ\96°ã\81\97ã\81¾ã\81\97ã\81\9f}} ($6 ã\82\92{{PLURAL:$7|追å\8a }}ã\80\81$8 ã\82\92{{PLURAL:$9|削除}})",
        "logentry-tag-update-logentry": "$1 がページ「$3」の記録項目 $5 のタグを{{GENDER:$2|更新しました}} ($6 を{{PLURAL:$7|追加}}、$8 を{{PLURAL:$9|削除}})",
        "rightsnone": "(なし)",
        "revdelete-summary": "編集内容の要約",
        "mw-widgets-dateinput-no-date": "選択されたデータ無し",
        "mw-widgets-titleinput-description-new-page": "ページは存在しません",
        "mw-widgets-titleinput-description-redirect": "$1 へのリダイレクト",
-       "api-error-blacklisted": "他の、説明的なタイトルをお選びください。",
        "sessionmanager-tie": "複数の要求の認証方法を組み合わせることはできません: $1。",
        "sessionprovider-generic": "$1 セッション",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "クッキーベースのセッション",
        "log-action-filter-newusers": "アカウント作成の種類:",
        "log-action-filter-patrol": "巡回の種類:",
        "log-action-filter-protect": "保護の種類:",
-       "log-action-filter-suppress": "秘匿の種類",
+       "log-action-filter-suppress": "秘匿の種類:",
        "log-action-filter-upload": "アップロードの種類",
        "log-action-filter-all": "すべて",
        "log-action-filter-block-block": "ブロック",
index 94f050f..516949e 100644 (file)
        "confirmable-confirm": "{{GENDER:$1|Sampéyan}} yakin?",
        "confirmable-yes": "Iya",
        "confirmable-no": "Ora",
-       "thisisdeleted": "Mirsani utawa mbalèkaké $1?",
+       "thisisdeleted": "Ndeleng utawa mbalèkaké $1?",
        "viewdeleted": "Deleng $1?",
-       "restorelink": "$1 {{PLURAL:$1|suntingan|suntingan}} sing wis kabusak",
+       "restorelink": "$1 {{PLURAL:$1|besutan}} sing wis dibusak",
        "feedlinks": "Asupan:",
        "feed-invalid": "Tipe permintaan asupan ora bener.",
        "feed-unavailable": "Umpan sindikasi (''syndication feeds'') ora kasedyakaké",
        "viewyourtext": "Sampéyan bisa ndeleng lan nyalin sumbering <strong>besutaning sampéyan</strong> ing kaca iki.",
        "protectedinterface": "Kaca iki isiné tèks antarmuka sing dienggo software lan wis dikunci kanggo menghindari kasalahan.",
        "editinginterface": "'''Pènget:''' Panjenengan nyunting kaca sing dianggo nyedyakaké tèks antarmuka kanggo piranti alus.\nPangowahan kaca iki bakal awèh pangaruh marang tampilan antarmuka panganggo kanggoné panganggo liya.\nKanggo terjemahan, mangga nganggo [https://translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net], proyèk lokalisasi MediaWiki.",
+       "translateinterface": "Kanggo nambah utawa ngowah pertalan kanggo kabèh wiki, mangga anggoa [https://translatewiki.net/ translatewiki.net] minangka proyèk palokaling MediaWiki.",
        "cascadeprotected": "Kaca iki wis direksa saka panyuntingan amerga disertakaké ing {{PLURAL:$1|kaca|kaca-kaca}} ngisor iki sing wis direksa mawa opsi \"runtun\" diaktifaké:\n$2",
        "namespaceprotected": "Panjenengan ora kagungan idin kanggo nyunting kaca ing bilik nama '''$1'''.",
        "customcssprotected": "Sampéyan ora dililakaké nyunting kaca CSS iki amarga kaisi pangaturan pribadi saka panganggo liya.",
        "parser-unstrip-loop-warning": "Unstrip loop detected",
        "parser-unstrip-recursion-limit": "Unstrip recursion limit exceeded ($1)",
        "converter-manual-rule-error": "Kasalahan kadètèk nèng aturan pangubahan basa manual",
-       "undo-success": "Suntingan iki bisa dibatalaké. Tulung priksa prabandhingan ing ngisor iki kanggo mesthèkaké yèn prakara iki pancèn sing bener panjenengan pèngin lakoni, banjur simpenen pangowahan iku kanggo ngrampungaké pambatalan suntingan.",
+       "undo-success": "Besutan iki kena diwurungaké.\nTiliki bandhingan ngisor iki saperlu mesthèkaké yèn bener iki sing arep kolakoni, nuli simpen owahan ngisor iki kanggo ngiyai yèn besutané diwurungaké.",
        "undo-failure": "Suntingan iki ora bisa dibatalakén amerga ana konflik panyuntingan antara.",
-       "undo-norev": "Suntingan iki ora bisa dibatalaké amerga ora ana utawa wis dibusak.",
-       "undo-summary": "Balèkaké owahan $1 déning [[Special:Contributions/$2|$2]] ([[User talk:$2|rembugan]])",
+       "undo-norev": "Besutan iki ora bisa diwurungaké amarga wis ora ana utawa wis dibusak.",
+       "undo-summary": "Mbalèkaké owahan $1 déning [[Special:Contributions/$2|$2]] ([[User talk:$2|rembugan]])",
        "undo-summary-username-hidden": "Batalna revisi $1 saking panganggo kang didhelikake",
        "cantcreateaccounttitle": "Akun ora bisa digawé",
        "cantcreateaccount-text": "Saka alamat IP iki ('''$1''') ora diparengaké nggawé akun utawa rékening. Sing mblokir utawa ora marengaké iku [[User:$3|$3]].\n\nAlesané miturut $3 yaiku ''$2''",
        "last": "sadurung",
        "page_first": "kapisan",
        "page_last": "pungkasan",
-       "histlegend": "Pilihen rong tombol radhio banjur pencèten tombol ''bandhingna'' kanggo mbandhingaké versi. Klik sawijining tanggal kanggo ndeleng versi kaca ing tanggal iku.<br />(skr) = prabédan karo vèrsi saiki, (akir) = prabédan karo vèrsi sadurungé, '''s''' = suntingan sithik, '''b''' = suntingan bot, → = suntingan bagian, ← = ringkesan otomatis",
+       "histlegend": "Kanggo mbandhingaké: tandhani kothak radhio révisi-révisi sing arep dibandhingaké lan pencèt ''Enter'' utawa tombol sing ana ing ngisor.<br />\nLegéndha: <strong>({{int:cur}})</strong> = béda karo révisi pungkasan, <strong>({{int:last}})</strong> = béda karo révisi sadurungé, <strong>{{int:minoreditletter}}</strong> = besutan cilik.",
        "history-fieldset-title": "Luru sujarah",
        "history-show-deleted": "Namung sing dibusak",
        "histfirst": "suwé dhéwé",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Prabédan",
        "prefs-help-prefershttps": "Pamiji iki bakal lumaku mentas sampeyan mbalèni mlebu.",
-       "prefs-tabs-navigation-hint": "Tip: Sampeyan isa nganggo dapat menggunakan tombol panah kiwa lan tengen kanggo navigasi tab-tab ing daftar tab.",
+       "prefs-tabs-navigation-hint": "Saran: Sampeyan bisa nganggo tombol jemparing kiwa lan tengen saperlu navigasi tab-tab ing pratélan tab.",
        "userrights": "Manajemen hak panganggo",
        "userrights-lookup-user": "Ngatur kelompok panganggo",
        "userrights-user-editname": "Isi jeneng panganggo:",
        "rcshowhidemine": "$1 besutanku",
        "rcshowhidemine-show": "Tuduhaké",
        "rcshowhidemine-hide": "Dhelikaké",
+       "rcshowhidecategorization": "$1 kategorisasi kaca",
        "rcshowhidecategorization-show": "Tuduhaké",
        "rcshowhidecategorization-hide": "Dhelikaké",
        "rclinks": "Tuduhaké $1 owahan kawit $2 dina kapungkur.<br />$3",
        "rc_categories": "Watesana nganti kategori (dipisah karo \"|\")",
        "rc_categories_any": "Apa waé",
        "rc-change-size-new": "$1 {{PLURAL:$1|bét|bét}} sabubaré diowah",
-       "newsectionsummary": "/* $1 */ bagéyan anyar",
+       "newsectionsummary": "/* $1 */ pérangan anyar",
        "rc-enhanced-expand": "Tuduhaké princèn",
        "rc-enhanced-hide": "Dhelikaké princèn",
        "rc-old-title": "kawitané digawé minangka \"$1\"",
        "wlheader-showupdated": "Kaca-kaca sing wis owah wiwit ditiliki panjenengan kaping pungkasan, dituduhaké mawa '''aksara kandel'''",
        "wlnote": "Ngisor iki {{PLURAL:$1|owahan pungkasan|'''$1''' owahan pungkasan}} {{PLURAL:$2|jam|'''$2''' jam}} kapungkur, per $3, $4.",
        "wlshowlast": "Tuduhna $1 jam $2 dina  pungkasan",
+       "wlshowhidecategorization": "kategorisasi kaca",
        "watchlist-options": "Pilihaning pawawangan",
        "watching": "Ngawasi...",
        "unwatching": "Ngilangi pangawasan...",
        "contribsub2": "Kanggo {{GENDER:$3|$1}} ($2)",
        "nocontribs": "Ora ditemokaké owah-owahan sing cocog karo kritéria kasebut iku.",
        "uctop": "(saiki)",
-       "month": "Wiwit wulan (lan sadurungé):",
+       "month": "Saka wulan (lan sadurungé):",
        "year": "Wiwit taun (lan sadurungé):",
        "sp-contributions-newbies": "Namung panganggo-panganggo anyar",
        "sp-contributions-newbies-sub": "Kanggo panganggo anyar",
        "immobile-target-namespace-iw": "Pranala interwiki dudu target sing sah kanggo pamindhahan kaca.",
        "immobile-source-page": "Kaca iki ora bisa dilih-lih.",
        "immobile-target-page": "Ora bisa mindhahaké menyang irah-irahan tujuan kasebut.",
-       "bad-target-model": "Halaman yang dituju menggunakan model isi yang berbeda. Tidak dapat mengonversi $1 ke $2.",
+       "bad-target-model": "Tujuan sing diarepaké nganggo gagrag isi sing béda. Ora bisa ngganti $1 dadi $2.",
        "imagenocrossnamespace": "Ora bisa mindhahaké gambar menyang bilik nama non-gambar",
        "nonfile-cannot-move-to-file": "Ora bisa mindhahaké non-berkas nèng bilik jeneng berkas",
        "imagetypemismatch": "Èkstènsi anyar berkas ora cocog karo jenisé",
        "import-error-interwiki": "Kaca \"$1\" ora diimpor amarga jenengé dicadhangaké kango pranala njaba (interwiki).",
        "import-error-special": "Kaca \"$1\" ora diimpor amarga kuwi kalebu nèng bilik jeneng kusus sing ora nglilakaké anané kaca.",
        "import-error-invalid": "Kaca \"$1\" ora diimpor amarga jenengé ora sah.",
-       "import-error-unserialize": "Revisi $2 dari halaman \"$1\" tidak dapat di-''unserialized''. Revisi tersebut dilaporkan menggunakan model konten $3 diserialisasi sebagai $4.",
+       "import-error-unserialize": "Revisi $2 saka kaca \"$1\" ora bisa diurutaké. Revisi iku dilapuraké murih nganggo gagrag isi $3 sing diurutaké minangka $4.",
        "import-options-wrong": "{{PLURAL:$2|Opsi|Opsi}} salah: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "Halaman turunan yang diberikan adalah judul yang salah.",
        "import-rootpage-nosubpage": "Ruang nama \"$1\" di halaman turunan tidak mengizinkan subhalaman.",
        "special-characters-group-thai": "Thailand",
        "special-characters-group-lao": "Lao",
        "special-characters-group-khmer": "Khmer",
-       "api-error-blacklisted": "Mangga pilih judhul liya sing njelasaké",
        "randomrootpage": "Kaca dhasaran waton"
 }
index 60500f1..8ec2e36 100644 (file)
        "mw-widgets-dateinput-placeholder-month": "წწწწ-თთ",
        "mw-widgets-titleinput-description-new-page": "გვერდი ჯერ არ არსებობს",
        "mw-widgets-titleinput-description-redirect": "გადამისამართება $1-ზე",
-       "api-error-blacklisted": "გთხოვთ, აირჩიეთ სხვა, აღწერილობითი სათაური.",
        "sessionmanager-tie": "შეუძლებელია მრავალი მოთხოვნის ავთენთიფიკაციის ტიპების გაერთიანება: $1.",
        "sessionprovider-generic": "$1 სესიები",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "cookie-სთან დაკავშირებული სესიები",
index e8d7ee9..b01984c 100644 (file)
        "history-show-deleted": "صرفی حذف شدہ",
        "histfirst": "قدیم ترین",
        "histlast": "تازہ ترین",
-       "historysize": "({{PLURAL:$1|1 بائٹ|$1 بائٹس}})",
+       "historysize": "({{PLURAL:$1|1 بائٹ|$1 بائٹ}})",
        "historyempty": "(خالی)",
        "history-feed-title": "تاریخچۂ نظرثانی",
        "history-feed-description": "ویکیپیڈیا ھیہ صفحو تاریخچۂ نظرثانی",
index d81fb26..5359a0d 100644 (file)
        "category_header": "\"$1\" 분류에 속하는 문서",
        "subcategories": "하위 분류",
        "category-media-header": "\"$1\" 분류에 속하는 미디어",
-       "category-empty": "<em>이 분류에는 문서나 자료가 하나도 없습니다.</em>",
+       "category-empty": "<em>현재 이 분류에는 문서나 미디어가 하나도 없습니다.</em>",
        "hidden-categories": "{{PLURAL:$1|숨은 분류|숨은 분류}}",
        "hidden-category-category": "숨은 분류",
        "category-subcat-count": "{{PLURAL:$2|이 분류에는 하위 분류 1개만이 속해 있습니다.|다음은 이 분류에 속하는 {{PLURAL:$1|하위 분류}} $2개 가운데 $1개입니다.}}",
        "internalerror": "내부 오류",
        "internalerror_info": "내부 오류: $1",
        "internalerror-fatal-exception": "종류 \"$1\"에서 심각한 오류",
-       "filecopyerror": "\"$1\" 파일을 \"$2\"로 복사할 수 없습니다.",
-       "filerenameerror": "\"$1\" 파일을 \"$2\"로 옮길 수 없습니다.",
+       "filecopyerror": "\"$1\" 파일을 \"$2\"(으)로 복사할 수 없습니다.",
+       "filerenameerror": "\"$1\" 파일을 \"$2\"(으)로 이름을 바꿀 수 없습니다.",
        "filedeleteerror": "\"$1\" 파일을 삭제할 수 없습니다.",
        "directorycreateerror": "\"$1\" 디렉터리를 만들 수 없습니다.",
        "directoryreadonlyerror": "\"$1\" 디렉터리는 읽기 전용입니다.",
        "password-login-forbidden": "이 사용자 계정 이름과 비밀번호는 사용할 수 없습니다.",
        "mailmypassword": "비밀번호 재설정",
        "passwordremindertitle": "{{SITENAME}}의 새 임시 비밀번호",
-       "passwordremindertext": "$1 IP ì£¼ì\86\8cì\97\90ì\84\9c ë\88\84êµ°ê°\80ê°\80 ì\95\84ë§\88 ì\9e\90ì\8b ì\9d´ {{SITENAME}} ($4)ì\9d\98 ì\83\88 ë¹\84ë°\80ë²\88í\98¸ë¥¼ ì\9a\94ì²­í\96\88ì\8aµë\8b\88ë\8b¤.\n\"$2\" ì\82¬ì\9a©ì\9e\90ì\9d\98 ì\9e\84ì\8b\9c ë¹\84ë°\80ë²\88í\98¸ë\8a\94 \"$3\"ë¡\9c ì\84¤ì \95ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤. ì\9d´ê²\83ì\9d´ ì\9e\90ì\8b ì\9d´ ì\9d\98ë\8f\84í\95\9c ë°\94ë\9d¼ë©´\nì§\80ê¸\88 ë¡\9cê·¸ì\9d¸í\95\98ì\97¬ ì\83\88ë¡\9cì\9a´ ë¹\84ë°\80ë²\88í\98¸ë¥¼ ë§\8cë\93\9cì\84¸ì\9a\94.\nì\9e\84ì\8b\9c ë¹\84ë°\80ë²\88í\98¸ë\8a\94 {{PLURAL:$5|$5일}} 후에 만료됩니다.\n\n이 요청을 다른 사람이 했거나 이전 비밀번호를 기억해 내서 바꿀 필요가 없으면\n이 메시지를 무시하고 이전 비밀번호를 계속 사용할 수 있습니다.",
+       "passwordremindertext": "$1 IP ì£¼ì\86\8cì\97\90ì\84\9c ë\8b¹ì\8b ì\9d¼ ì\88\98ë\8f\84 ì\9e\88ë\8a\94 ë\88\84êµ°ê°\80ê°\80 {{SITENAME}} ($4)ì\9d\98 ì\83\88 ë¹\84ë°\80ë²\88í\98¸ë¥¼ ì\9a\94ì²­í\96\88ì\8aµë\8b\88ë\8b¤.\n\"$2\" ì\82¬ì\9a©ì\9e\90ì\9d\98 ì\9e\84ì\8b\9c ë¹\84ë°\80ë²\88í\98¸ë\8a\94 \"$3\"ë¡\9c ì\84¤ì \95ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤. ì\9d´ê²\83ì\9d´ ì\9e\90ì\8b ì\9d´ ì\9d\98ë\8f\84í\95\9c ë°\94ë\9d¼ë©´\nì§\80ê¸\88 ë¡\9cê·¸ì\9d¸í\95\98ì\97¬ ì\83\88ë¡\9cì\9a´ ë¹\84ë°\80ë²\88í\98¸ë¥¼ ë§\8cë\93\9cì\84¸ì\9a\94.\nì\9e\84ì\8b\9c ë¹\84ë°\80ë²\88í\98¸ë\8a\94 {{PLURAL:$5|1ì\9d¼|$5일}} 후에 만료됩니다.\n\n이 요청을 다른 사람이 했거나 이전 비밀번호를 기억해 내서 바꿀 필요가 없으면\n이 메시지를 무시하고 이전 비밀번호를 계속 사용할 수 있습니다.",
        "noemail": "\"$1\" 사용자는 이메일 주소를 등록하지 않았습니다.",
        "noemailcreate": "올바른 이메일 주소를 제공해야 합니다.",
        "passwordsent": "\"$1\" 계정의 새로운 비밀번호를 이메일로 보냈습니다.\n비밀번호를 받고 다시 로그인해 주세요.",
        "accountcreated": "계정이 만들어짐",
        "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|토론]]) 사용자 계정이 만들어졌습니다.",
        "createaccount-title": "{{SITENAME}} 계정 만들기",
-       "createaccount-text": "ë\88\84êµ°ê°\80ê°\80 {{SITENAME}} ($4)ì\97\90ì\84\9c ì\82¬ì\9a©ì\9e\90 ì\9d´ë¦\84 \"$2\", ë¹\84ë°\80ë²\88í\98¸ \"$3\"ë¡\9c ë\8b¹ì\8b ì\9d\98 ì\9d´ë©\94ì\9d¼ ì£¼ì\86\8cê°\80 ë\93±ë¡\9dë\90\9c ê³\84ì \95ì\9d\84 ë§\8cë\93¤ì\97\88ì\8aµë\8b\88ë\8b¤. \nì§\80ê¸\88 ë¡\9cê·¸ì\9d¸í\95\98ì\97¬ ë¹\84ë°\80ë²\88í\98¸ë¥¼ ë°\94꾸ì\8b­ì\8b\9cì\98¤.\n\nì\8b¤ì\88\98ë¡\9c ê³\84ì \95ì\9d\84 ì\9e\98못 ë§\8cë\93¤ì\97\88ë\8b¤ë©´ ì\9d´ ë©\94ì\8b\9cì§\80ë\8a\94 ë¬´ì\8b\9cí\95´ë\8f\84 ë\90©ë\8b\88ë\8b¤.",
+       "createaccount-text": "ë\88\84êµ°ê°\80ê°\80 {{SITENAME}} ($4)ì\97\90ì\84\9c ì\82¬ì\9a©ì\9e\90 ì\9d´ë¦\84 \"$2\", ë¹\84ë°\80ë²\88í\98¸ \"$3\"ë¡\9c ë\8b¹ì\8b ì\9d\98 ì\9d´ë©\94ì\9d¼ ì£¼ì\86\8cê°\80 ë\93±ë¡\9dë\90\9c ê³\84ì \95ì\9d\84 ë§\8cë\93¤ì\97\88ì\8aµë\8b\88ë\8b¤. \nì§\80ê¸\88 ë¡\9cê·¸ì\9d¸í\95\98ì\97¬ ë¹\84ë°\80ë²\88í\98¸ë¥¼ ë°\94꾸ì\85\94ì\95¼ í\95©ë\8b\88ë\8b¤.\n\nì\8b¤ì\88\98ë¡\9c ê³\84ì \95ì\9d\84 ì\9e\98못 ë§\8cë\93¤ì\97\88ë\8b¤ë©´ ì\9d´ ë©\94ì\8b\9cì§\80ë\8a\94 ë¬´ì\8b\9cí\95´ë\8f\84 ë\90©ë\8b\88ë\8b¤.",
        "login-throttled": "최근 너무 많이 로그인을 시도했습니다.\n$1 뒤에 다시 시도하세요.",
        "login-abort-generic": "로그인에 실패했습니다 - 중지됨",
        "login-migrated-generic": "당신의 계정이 마이그레이션되었으며, 당신의 사용자 이름이 더 이상 이 위키에 존재하지 않습니다.",
        "botpasswords-updated-body": "사용자 \"$2\"의 \"$1\"라는 이름의 봇 비밀번호가 업데이트되었습니다.",
        "botpasswords-deleted-title": "봇 비밀번호 제거",
        "botpasswords-deleted-body": "사용자 \"$2\"의 \"$1\"라는 이름의 봇 비밀번호가 삭제되었습니다.",
-       "botpasswords-newpassword": "<strong>$1</strong> 계정의 비밀번호가 <strong>$2</strong>로 변경되었습니다. <em>잊어버리지 않도록 기록해두시기 바랍니다.</em>",
+       "botpasswords-newpassword": "<strong>$1</strong>님으로 로그인하기 위한 새 비밀번호가 <strong>$2</strong>입니다. <em>잊어버리지 않도록 기록해두시기 바랍니다.</em>",
        "botpasswords-no-provider": "'BotPasswordsSessionProvider'는 이용할 수 없습니다.",
        "botpasswords-restriction-failed": "봇 비밀번호 제한으로 인해 로그인할 수 없습니다.",
        "botpasswords-invalid-name": "지정된 사용자 이름은 봇 비밀번호 구분자(\"$1\")를 포함하고 있지 않습니다.",
        "passwordreset-capture-help": "이 상자에 체크하면 이메일이 발송된 즉시 임시 비밀번호가 담긴 이메일을 볼 수 있습니다.",
        "passwordreset-email": "이메일 주소:",
        "passwordreset-emailtitle": "{{SITENAME}} 계정에 대한 자세한 정보",
-       "passwordreset-emailtext-ip": "$1 IP 주소를 사용하는 누군가가 아마 자신이 {{SITENAME}} ($4)의 비밀번호 재설정을 요청하였습니다.\n이 이메일 주소와 연관된 {{PLURAL:$3|계정}}의 목록입니다:\n\n$2\n\n{{PLURAL:$3|이 임시 비밀번호}}는 {{PLURAL:$5|$5일}} 후에 만료됩니다.\n이 비밀번호로 로그인한 후 비밀번호를 바꾸십시오. 만약 당신이 아닌 다른 사람이 요청하였거나,\n원래의 비밀번호를 기억해냈다면, 이 메시지를 무시하고\n이전의 비밀번호를 계속 사용할 수 있습니다.",
+       "passwordreset-emailtext-ip": "당신일 수도 있는 $1 IP 주소를 사용하는 사용자가 {{SITENAME}} ($4)의 비밀번호 재설정을 요청하였습니다.\n이 이메일 주소와 연관된 {{PLURAL:$3|계정}}의 목록입니다:\n\n$2\n\n{{PLURAL:$3|이 임시 비밀번호}}는 {{PLURAL:$5|1일|$5일}} 후에 만료됩니다.\n이 비밀번호로 로그인한 후 비밀번호를 바꾸십시오. 만약 당신이 아닌 다른 사람이 요청하였거나,\n원래의 비밀번호를 기억해냈다면, 이 메시지를 무시하고\n이전의 비밀번호를 계속 사용할 수 있습니다.",
        "passwordreset-emailtext-user": "{{SITENAME}} ($4)의 사용자 $1이 비밀번호 재설정을 요청하였습니다.\n이 이메일 주소와 연관된 {{PLURAL:$3|계정}}의 목록입니다:\n\n$2\n\n{{PLURAL:$3|이 임시 비밀번호}}는 {{PLURAL:$5|$5일}} 후에 만료됩니다.\n이 비밀번호로 로그인한 후 비밀번호를 바꾸십시오. 만약 당신이 아닌 다른 사람이 요청하였거나,\n원래의 비밀번호를 기억해냈다면, 이 메시지를 무시하고\n이전의 비밀번호를 계속 사용할 수 있습니다.",
        "passwordreset-emailelement": "사용자 이름: \n$1\n\n임시 비밀번호: \n$2",
        "passwordreset-emailsentemail": "당신의 계정과 연결된 이메일 주소가 있다면, 비밀번호 재설정 메일이 전해질 것입니다.",
        "loginreqlink": "로그인",
        "loginreqpagetext": "다른 문서를 보기 위해서는 $1해야 합니다.",
        "accmailtitle": "비밀번호를 보냈습니다",
-       "accmailtext": "[[User talk:$1|$1]] 사용자의 비밀번호를 임의로 만들어 $2(으)로 보냈습니다. 로그인하고 나서 <em>[[Special:ChangePassword|비밀번호를 바꿀]]</em> 수 있습니다.",
+       "accmailtext": "[[User talk:$1|$1]]의 비밀번호를 임의로 만들어 $2(으)로 보냈습니다. 로그인하고 나서 <em>[[Special:ChangePassword|비밀번호를 바꿀]]</em> 수 있습니다.",
        "newarticle": "(새 문서)",
        "newarticletext": "아직 없는 문서의 링크를 따라왔습니다.\n새 문서를 만들려면 아래 상자에 내용을 입력하면 됩니다. (자세한 내용은 [$1 도움말 문서]를 참조하세요)\n만약 잘못 찾아왔다면, 브라우저의 '''뒤로''' 버튼을 눌러 주세요.",
        "anontalkpagetext": "----\n여기는 계정을 만들지 않았거나 사용하고 있지 않은 익명 사용자를 위한 토론 문서입니다.\n익명 사용자를 구별하기 위해서는 숫자로 된 IP 주소를 사용해야만 합니다.\nIP 주소는 여러 사용자가 공유할 수 있습니다.\n자신과 관계없는 의견이 자신에게 남겨져 있어 불쾌하다고 생각하는 익명 사용자는 [[Special:CreateAccount|계정을 만들고]] [[Special:UserLogin|로그인해서]] 나중에 다른 익명 사용자에게 줄 혼란을 줄일 수 있습니다.",
        "content-not-allowed-here": "\"$1\" 내용은 [[$2]] 문서예 허용하지 않습니다",
        "editwarning-warning": "이 페이지에서 벗어나면 저장하지 않은 바뀜이 모두 사라집니다.\n로그인을 했다면, 환경 설정의 \"{{int:편집 상자}}\"에서 이 경고를 띄우지 않도록 설정할 수 있습니다.",
        "editpage-notsupportedcontentformat-title": "지원하지 않는 내용 형식",
-       "editpage-notsupportedcontentformat-text": "내용 형식 $1(은)는 $2 내용 모델에서 지원하지 않습니다.",
+       "editpage-notsupportedcontentformat-text": "내용 형식 $1은(는) $2 내용 모델에서 지원하지 않습니다.",
        "content-model-wikitext": "위키텍스트",
        "content-model-text": "일반 텍스트",
        "content-model-javascript": "자바스크립트",
        "content-model-css": "CSS",
        "content-json-empty-object": "빈 오브젝트",
        "content-json-empty-array": "빈 배열",
+       "deprecated-self-close-category": "유효하지 않은, 스스로 닫는 HTML 태그를 사용하고 있는 문서",
+       "deprecated-self-close-category-desc": "이 문서는 <code>&lt;b/></code>나 <code>&lt;span/></code>와 같은 유효하지 않은, 스스로 닫는 HTML 태그를 포함하고 있습니다. 이 태그들의 동작은 곧 HTML5 사양과 일관되도록 변경될 예정이므로 위키텍스트에서 이것들을 사용하는 것은 권장되지 않습니다.",
        "duplicate-args-warning": "<strong>경고:</strong> [[:$1]] 문서는 [[:$2]]에 \"$3\" 변수를 하나보다 더 많이 입력했습니다. 마지막으로 주어진 값만이 유효합니다.",
        "duplicate-args-category": "중복된 인수를 사용한 틀의 호출을 포함한 문서",
        "duplicate-args-category-desc": "문서에 <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code>나 <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>와 같은, 인수를 중복하여 사용한 틀 호출을 포함합니다.",
        "minlength1": "파일 이름은 적어도 1글자 이상이어야 합니다.",
        "illegalfilename": "파일 이름 \"$1\"에는 문서 제목에 허용되지 않는 글자가 포함되어 있습니다.\n이름을 바꾸어 다시 시도해 주세요.",
        "filename-toolong": "파일 이름은 240바이트를 넘을 수 없습니다.",
-       "badfilename": "파일 이름이 \"$1\"로 바뀌었습니다.",
+       "badfilename": "파일 이름이 \"$1\"(으)로 바뀌었습니다.",
        "filetype-mime-mismatch": "\".$1\" 파일 확장자와 이 파일의 MIME 형식($2)이 일치하지 않습니다.",
        "filetype-badmime": "\"$1\" MIME 형식을 가진 파일은 올릴 수 없습니다.",
-       "filetype-bad-ie-mime": "이 파일을 올릴 수 없습니다. Internet Explorer가 잠재적으로 위험한 파일 형식으로 판단하여 사용이 금지된 \"$1\"로 인식할 수 있습니다.",
+       "filetype-bad-ie-mime": "이 파일을 올릴 수 없습니다. Internet Explorer가 잠재적으로 위험한 파일 형식으로 판단하여 사용이 금지된 \"$1\"(으)로 인식할 수 있습니다.",
        "filetype-unwanted-type": "'''\".$1\"''' 확장자는 권장하지 않습니다.\n권장하는 {{PLURAL:$3|파일 확장자}}는 $2입니다.",
        "filetype-banned-type": "'''\".$1\"''' {{PLURAL:$4|형식의 파일은 올릴 수 없습니다}}.\n$2 {{PLURAL:$3|형식만 사용할 수 있습니다}}.",
        "filetype-missing": "파일에 확장자(\".jpg\" 등)가 없습니다.",
        "backend-fail-notexists": "$1 파일이 존재하지 않습니다.",
        "backend-fail-hashes": "비교 해시값을 얻지 못했습니다.",
        "backend-fail-notsame": "\"$1\" 파일과 같은 이름을 가진 다른 파일이 존재합니다.",
-       "backend-fail-invalidpath": "\"$1\"(은)는 올바른 저장소 경로가 아닙니다.",
+       "backend-fail-invalidpath": "\"$1\"은(는) 올바른 저장소 경로가 아닙니다.",
        "backend-fail-delete": "\"$1\" 파일을 삭제할 수 없습니다.",
        "backend-fail-describe": "\"$1\" 파일에 대한 메타데이터를 바꿀 수 없습니다.",
        "backend-fail-alreadyexists": "\"$1\" 파일이 이미 존재합니다.",
        "img-auth-public": "img_auth.php는 개인 위키 파일을 바깥 사이트로 전송하는 기능입니다.\n이 기능은 기본적으로 공개적인 위키에서 사용하도록 설계되어 있습니다.\n보안적인 문제로 기본적으로 img_auth.php 기능은 비활성화되어 있습니다.",
        "img-auth-noread": "\"$1\" 파일을 볼 권한이 없습니다.",
        "http-invalid-url": "잘못된 URL: $1",
-       "http-invalid-scheme": "\"$1\"로 시작하는 URL은 지원되지 않습니다.",
+       "http-invalid-scheme": "\"$1\"(으)로 시작하는 URL은 지원되지 않습니다.",
        "http-request-error": "알 수 없는 오류로 HTTP 요청에 실패했습니다.",
        "http-read-error": "HTTP 읽기 오류입니다.",
        "http-timed-out": "HTTP 요청 시간 초과입니다.",
        "randompage": "임의 문서로",
        "randompage-nopages": "{{PLURAL:$2|다음}} 이름공간에는 문서가 없습니다: $1",
        "randomincategory": "분류 안의 임의 문서",
-       "randomincategory-invalidcategory": "\"$1\"(은)는 올바른 분류 이름이 아닙니다.",
+       "randomincategory-invalidcategory": "\"$1\"은(는) 올바른 분류 이름이 아닙니다.",
        "randomincategory-nopages": "[[:Category:$1]]에 문서가 없습니다.",
        "randomincategory-category": "분류:",
        "randomincategory-legend": "분류 안의 임의 문서",
        "listgrants-grant": "부여",
        "listgrants-rights": "권한",
        "trackingcategories": "추적용 분류",
-       "trackingcategories-summary": "이 페이지는 미디어위키 소프트웨어에 의해 자동으로 만들어지는 추적용 분류를 나열합니다. 그들의 이름은 {{ns:8}} 이름공간에 관련된 시스템 메시지를 바꾸어서 바꿀 수 있습니다.",
+       "trackingcategories-summary": "이 페이지는 미디어위키 소프트웨어에 의해 자동으로 만들어지는 추적용 분류를 나열합니다. 이들의 이름은 {{ns:8}} 이름공간의 관련 시스템 메시지들을 변경함으로써 바꿀 수 있습니다.",
        "trackingcategories-msg": "추적용 분류",
        "trackingcategories-name": "메시지 이름",
        "trackingcategories-desc": "분류 포함 기준",
        "enotif_subject_created": "{{SITENAME}} $1 문서를 $2 사용자가 {{GENDER:$2|만들었습니다}}",
        "enotif_subject_moved": "{{SITENAME}} $1 문서를 $2 사용자가 {{GENDER:$2|이동하였습니다}}",
        "enotif_subject_restored": "{{SITENAME}} $1 문서를 $2 사용자가 {{GENDER:$2|되살렸습니다}}",
-       "enotif_subject_changed": "{{SITENAME}} $1 문서를 $2 사용자가 {{GENDER:$2|바꾸었습니다}}",
+       "enotif_subject_changed": "{{SITENAME}} $1 문서를 $2님이 {{GENDER:$2|바꾸었습니다}}",
        "enotif_body_intro_deleted": "{{SITENAME}} $1 문서를 $PAGEEDITDATE에 $2 사용자가 {{GENDER:$2|삭제했으며}} $3 에서 볼 수 있습니다.",
        "enotif_body_intro_created": "{{SITENAME}} $1 문서를 $PAGEEDITDATE에 $2 사용자가 {{GENDER:$2|만들었으며}} 현재 판은 $3 에서 볼 수 있습니다.",
        "enotif_body_intro_moved": "{{SITENAME}} $1 문서를 $PAGEEDITDATE에 $2 사용자가 {{GENDER:$2|이동하였으며}} 현재 판은 $3 에서 볼 수 있습니다.",
        "log-name-contentmodel": "콘텐츠 모델 변경 기록",
        "log-description-contentmodel": "페이지의 콘텐츠 모델과 관련된 행위",
        "logentry-contentmodel-new": "$1님이 비 기본값 \"$5\" 콘텐츠 모델을 사용해  $3 문서를 {{GENDER:$2|만들었습니다}}",
-       "logentry-contentmodel-change": "$1님이 $3 문서의 콘텐츠 모델을 \"$4\"에서 \"$5\"로 {{GENDER:$2|바꾸었습니다}}",
+       "logentry-contentmodel-change": "$1님이 $3 문서의 콘텐츠 모델을 \"$4\"에서 \"$5\"(으)로 {{GENDER:$2|바꾸었습니다}}",
        "logentry-contentmodel-change-revertlink": "되돌리기",
        "logentry-contentmodel-change-revert": "되돌리기",
        "protectlogpage": "문서 보호 기록",
        "protectedarticle": "사용자가 \"[[$1]]\" 문서를 보호했습니다",
        "modifiedarticleprotection": "사용자가 \"[[$1]]\" 문서의 보호 설정을 바꿨습니다",
        "unprotectedarticle": "사용자가 \"[[$1]]\" 문서를 보호 해제했습니다",
-       "movedarticleprotection": "사용자가 문서의 보호 설정을 \"[[$2]]\"에서 \"[[$1]]\"으로 변경했습니다",
+       "movedarticleprotection": "사용자가 문서의 보호 설정을 \"[[$2]]\"에서 \"[[$1]]\"(으)로 이동했습니다",
        "protect-title": "\"$1\" 보호하기",
        "protect-title-notallowed": "\"$1\" 문서의 보호 수준 보기",
        "prot_1movedto2": "[[$1]] 문서를 [[$2]] 문서로 옮김",
        "anonymous": "{{SITENAME}} 익명 {{PLURAL:$1|사용자}}",
        "siteuser": "{{SITENAME}} 사용자 $1",
        "anonuser": "{{SITENAME}} 익명 사용자 $1",
-       "lastmodifiedatby": "이 문서는 $3 사용자가 $1 $2에 마지막으로 바꾸었습니다.",
+       "lastmodifiedatby": "이 문서는 $3님이 $1 $2에 마지막으로 바꾸었습니다.",
        "othercontribs": "$1의 작업을 바탕으로 합니다.",
        "others": "기타",
        "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|사용자}}}} $1",
        "spamprotectiontext": "스팸 필터가 문서 저장을 막았습니다.\n바깥 사이트로 연결하는 링크 중에 블랙리스트에 포함된 사이트가 있을 것입니다.",
        "spamprotectionmatch": "문제가 되는 부분은 다음과 같습니다: $1",
        "spambot_username": "미디어위키 스팸 정리",
-       "spam_reverting": "$1(을)를 포함하지 않는 최신 버전으로 되돌림",
+       "spam_reverting": "$1에 대한 링크를 포함하지 않는 최신 버전으로 되돌림",
        "spam_blanking": "모든 버전에 $1 링크를 포함하고 있어 차단함",
        "spam_deleting": "모든 버전에 $1 링크를 포함하고 있어 삭제함",
        "simpleantispam-label": "스팸 방지 검사입니다.\n이것을 입력하지 <strong>마세요</strong>!",
        "confirmemail_success": "이메일 주소가 인증되었습니다.\n이제 [[Special:UserLogin|로그인]]해서 위키를 사용하세요.",
        "confirmemail_loggedin": "이메일 주소가 인증되었습니다.",
        "confirmemail_subject": "{{SITENAME}} 이메일 주소 인증",
-       "confirmemail_body": "$1 IP 주소를 사용하는 사용자가\n{{SITENAME}}의 \"$2\" 계정에 이메일 인증 신청을 했습니다.\n\n이 계정이 당신의 계정이고 {{SITENAME}}에서 이메일 기능을 활성화하려면\n아래 주소를 열어서 이메일 인증을 해 주세요:\n\n$3\n\n당신의 계정이 아니라면,\n이메일 인증 신청을 취소하기 위해 아래의 주소를 열어주세요:\n\n$5\n\n인증 코드는 $4에 만료됩니다.",
-       "confirmemail_body_changed": "$1 IP 주소를 사용하는 사용자가\n{{SITENAME}}의 \"$2\" 계정의 이메일 주소를 바꾸었습니다.\n\n이 계정이 당신의 계정이고 {{SITENAME}}에서 이메일 기능을 활성화하려면\n아래 주소를 열어서 이메일 인증을 해 주세요:\n\n$3\n\n당신의 계정이 아니라면,\n이메일 인증 신청을 취소하기 위해 아래의 주소를 열어주세요:\n\n$5\n\n인증 코드는 $4에 만료됩니다.",
-       "confirmemail_body_set": "$1 IP 주소를 사용하는 사용자가\n{{SITENAME}}의 \"$2\" 계정의 이메일 주소를 지정하였습니다.\n\n이 계정이 당신의 계정이고 {{SITENAME}}에서 이메일 기능을\n활성화하려면 아래 주소를 열어서 이메일 인증을 해 주세요:\n\n$3\n\n당신의 계정이 아니라면,\n이메일 인증 신청을 취소하기 위해 아래의 주소를 열어주세요:\n\n$5\n\n인증 코드는 $4에 만료됩니다.",
+       "confirmemail_body": "당신일 수도 있는 $1 IP 주소를 사용하는 사용자가\n{{SITENAME}}의 \"$2\" 계정에 이메일 인증 신청을 했습니다.\n\n이 계정이 당신의 계정이고 {{SITENAME}}에서 이메일 기능을 활성화하려면\n아래 주소를 열어서 이메일 인증을 해 주세요:\n\n$3\n\n당신의 계정이 아니라면,\n이메일 인증 신청을 취소하기 위해 아래의 주소를 열어주세요:\n\n$5\n\n인증 코드는 $4에 만료됩니다.",
+       "confirmemail_body_changed": "당신일 수도 있는 $1 IP 주소를 사용하는 사용자가\n{{SITENAME}}의 \"$2\" 계정의 이메일 주소를 바꾸었습니다.\n\n이 계정이 당신의 계정이고 {{SITENAME}}에서 이메일 기능을 활성화하려면\n아래 주소를 열어서 이메일 인증을 해 주세요:\n\n$3\n\n당신의 계정이 아니라면,\n이메일 인증 신청을 취소하기 위해 아래의 주소를 열어주세요:\n\n$5\n\n인증 코드는 $4에 만료됩니다.",
+       "confirmemail_body_set": "당신일 수도 있는 $1 IP 주소를 사용하는 사용자가\n{{SITENAME}}의 \"$2\" 계정의 이메일 주소를 지정하였습니다.\n\n이 계정이 당신의 계정이고 {{SITENAME}}에서 이메일 기능을\n활성화하려면 아래 주소를 열어서 이메일 인증을 해 주세요:\n\n$3\n\n당신의 계정이 아니라면,\n이메일 인증 신청을 취소하기 위해 아래의 주소를 열어주세요:\n\n$5\n\n인증 코드는 $4에 만료됩니다.",
        "confirmemail_invalidated": "이메일 확인이 취소됨",
        "invalidateemail": "이메일 확인 취소",
        "notificationemail_subject_changed": "{{SITENAME}}의 등록된 이메일 주소가 변경되었습니다",
        "notificationemail_subject_removed": "{{SITENAME}}의 등록된 이메일 주소가 제거되었습니다",
-       "notificationemail_body_changed": "IP 주소 $1에 속하는 누군가가 {{SITENAME}}의 사용자 \"$2\" 계정의 이메일 주소를 \"$3\"으로 변경하였습니다.\n\n지금 이 글을 보고 계신 사용자로 추정되지만 만약 본인이 아닌 경우, 지금 바로 사이트 관리자에게 문의하십시오.",
-       "notificationemail_body_removed": "IP 주소 $1에 속하는 누군가가 {{SITENAME}}의 사용자 \"$2\" 계정의 이메일 주소를 제거하였습니다.\n\n지금 이 글을 보고 계신 사용자로 추정되지만 만약 본인이 아닌 경우, 지금 바로 사이트 관리자에게 문의하십시오.",
+       "notificationemail_body_changed": "당신일 수도 있는 IP 주소 $1에 속하는 사용자가\n{{SITENAME}}의 사용자 \"$2\" 계정의 이메일 주소를 \"$3\"(으)로 바꾸었습니다.\n\n지금 이 글을 보고 계신 사용자로 추정되지만 만약 본인이 아닌 경우, 지금 바로 사이트 관리자에게 문의하십시오.",
+       "notificationemail_body_removed": "당신일 수도 있는 IP 주소 $1에 속하는 사용자가 {{SITENAME}}의 사용자 \"$2\" 계정의 이메일 주소를 제거하였습니다.\n\n지금 이 글을 보고 계신 사용자로 추정되지만 만약 본인이 아닌 경우, 지금 바로 사이트 관리자에게 문의하십시오.",
        "scarytranscludedisabled": "[인터위키가 비활성되어 있습니다]",
        "scarytranscludefailed": "[$1 틀을 불러오는 데에 실패했습니다]",
        "scarytranscludefailed-httpstatus": "[$1 틀을 가져오는 데 실패했습니다: HTTP $2]",
        "table_pager_limit_submit": "확인",
        "table_pager_empty": "결과 없음",
        "autosumm-blank": "문서를 비움",
-       "autosumm-replace": "문ì\84\9c ë\82´ì\9a©ì\9d\84 \"$1\"ì\9c¼로 바꿈",
+       "autosumm-replace": "ë\82´ì\9a©ì\9d\84 \"$1\"(ì\9c¼)로 바꿈",
        "autoredircomment": "[[$1]] 문서로 넘겨주기",
        "autosumm-new": "새 문서: $1",
        "autosumm-newblank": "빈 문서를 만듦",
        "logentry-suppress-delete": "$1님이 $3 문서를 {{GENDER:$2|숨겼습니다}}",
        "logentry-suppress-event": "$1님이 비공개적으로 $3의 {{PLURAL:$5|기록 $5개}}에 대해 보이기 설정을 {{GENDER:$2|바꾸었습니다}}: $4",
        "logentry-suppress-revision": "$1님이 비공개적으로 $3 문서의 {{PLURAL:$5|판 $5개}}에 대해 보이기 설정을 {{GENDER:$2|바꾸었습니다}}: $4",
-       "logentry-suppress-event-legacy": "$1님이 비공개적으로 $3의 항목에 대한 보이기 설정을 {{GENDER:$2|바꾸었습니다}}",
+       "logentry-suppress-event-legacy": "$1님이 비공개적으로 $3의 기록 항목에 대한 보이기 설정을 {{GENDER:$2|바꾸었습니다}}",
        "logentry-suppress-revision-legacy": "$1님이 비공개적으로 $3 문서의 특정 판에 대한 보이기 설정을 {{GENDER:$2|바꾸었습니다}}",
        "revdelete-content-hid": "내용 숨겨짐",
        "revdelete-summary-hid": "편집 요약 숨겨짐",
        "revdelete-unrestricted": "관리자에 대한 제한을 해제함",
        "logentry-block-block": "$1님이 {{GENDER:$4|$3}}님을 $5 {{GENDER:$2|차단했습니다}} $6",
        "logentry-block-unblock": "$1님이 {{GENDER:$4|$3}} 사용자의 {{GENDER:$2|차단을 해제했습니다}}",
-       "logentry-block-reblock": "$1 님이 {{GENDER:$4|$3}} 사용자의 차단 기간을 $5 설정으로 {{GENDER:$2|바꾸었습니다}} $6",
+       "logentry-block-reblock": "$1님이 {{GENDER:$4|$3}}님의 차단 기간을 $5 설정으로 {{GENDER:$2|바꾸었습니다}} $6",
        "logentry-suppress-block": "$1님이 {{GENDER:$4|$3}} 사용자를 $5 {{GENDER:$2|차단했습니다}} $6",
-       "logentry-suppress-reblock": "$1 님이 {{GENDER:$4|$3}} 사용자의 차단 기간을 $5 설정으로 {{GENDER:$2|바꾸었습니다}} $6",
+       "logentry-suppress-reblock": "$1님이 {{GENDER:$4|$3}}님의 차단 기간을 $5 설정으로 {{GENDER:$2|바꾸었습니다}} $6",
        "logentry-import-upload": "$1님이 $3 문서를 파일 올리기로 {{GENDER:$2|가져왔습니다}}",
        "logentry-import-upload-details": "$1님이 $3 문서 ({{PLURAL:$4|판}} $4개)를 파일 올리기로 {{GENDER:$2|가져왔습니다}}",
        "logentry-import-interwiki": "$1님이 $3 문서를 다른 위키에서 {{GENDER:$2|가져왔습니다}}",
        "logentry-protect-protect-cascade": "$1님이 $3 문서를 {{GENDER:$2|보호했습니다}} $4 [연쇄적]",
        "logentry-protect-modify": "$1님이 $3 문서의 보호 수준을 {{GENDER:$2|바꾸었습니다}} $4",
        "logentry-protect-modify-cascade": "$1님이 $3 문서의 보호 수준을 {{GENDER:$2|바꾸었습니다}} $4 [연쇄적]",
-       "logentry-rights-rights": "$1님이 $3 사용자의 권한을 $4에서 $5(으)로 {{GENDER:$2|바꾸었습니다}}",
+       "logentry-rights-rights": "$1님이 {{GENDER:$6|$3}}님의 권한을 $4에서 $5(으)로 {{GENDER:$2|바꾸었습니다}}",
        "logentry-rights-rights-legacy": "$1님이 $3 사용자의 권한을 {{GENDER:$2|바꾸었습니다}}",
        "logentry-rights-autopromote": "$1님이 권한을 자동적으로 $4에서 $5으로 {{GENDER:$2|바꾸었습니다}}",
        "logentry-upload-upload": "$1님이 $3 파일을 {{GENDER:$2|올렸습니다}}",
        "mw-widgets-dateinput-no-date": "선택된 날짜 없음",
        "mw-widgets-titleinput-description-new-page": "문서가 존재하지 않습니다",
        "mw-widgets-titleinput-description-redirect": "$1 문서로 넘겨주기",
-       "api-error-blacklisted": "이 파일을 설명할 수 있는 다른 제목을 선택하세요.",
        "sessionmanager-tie": "여러 요청 인증 유형 결합할 수 없습니다: $1.",
        "sessionprovider-generic": "$1 세션",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "쿠키 기반 세션",
        "log-action-filter-newusers": "계정 생성 종류:",
        "log-action-filter-patrol": "점검 종류:",
        "log-action-filter-protect": "보호 종류:",
-       "log-action-filter-rights": "권한 변경 종류",
-       "log-action-filter-suppress": "숨기기 종류",
+       "log-action-filter-rights": "권한 변경 종류:",
+       "log-action-filter-suppress": "숨기기 종류:",
        "log-action-filter-upload": "업로드 종류:",
        "log-action-filter-all": "모두",
        "log-action-filter-block-block": "차단",
index fb4c899..907f767 100644 (file)
        "nocookiesnew": "Dinge neue Metmaacher Name es enjerich, ävver dat automatisch Enlogge wor dann nix.\nSchad.\n{{ucfirst:{{GRAMMAR:Nom|{{SITENAME}}}}}} bruch Cookies, öm ze merke, wä enjelogg es.\nWann De Cookies avjeschald häs en Dingem Brauser, dann kann dat nit laufe.\nSök Der ene Brauser, dä et kann, dun se enschalte, un dann log Dich noch ens neu en, met Dingem neue Metmaacher Name un Passwood.",
        "nocookieslogin": "{{ucfirst:{{GRAMMAR:Nominativ|{{SITENAME}}}}}} bruch <i lang=\"en\">cookies</i> för et Enlogge. Et süht esu us, als hätts De de <i lang=\"en\">cookies</i> avjeschalt. Dun se aanschalte un dann versök et noch ens. Odder söök Der ene Brauser, dä et kann.",
        "nocookiesfornew": "Et wood keine Zohjang opjemaat, weil mer nit jeweß sin künne, woh de Daate her kohme.\nDinge Brauser moß <i lang=\"en\">cookies</i> enjeschalldt han.\nDonn dat prööfe, donn heh di Sigg norr_ens neu laade, un dann versöhk et norr_ens.",
+       "nocookiesforlogin": "{{int:nocookieslogin}}",
        "noname": "Dat jeiht nit als ene Metmaacher Name. Jetz muss De et noch ens versöke.",
        "loginsuccesstitle": "Enjelogg",
        "loginsuccess": "'''Do bes jetz enjelogg {{GRAMMAR:en|{{SITENAME}}}}, un Dinge Name als ene Metmaacher es „$1“.'''",
-       "nosuchuser": "Dä Metmaacher Name „$1“ wor verkihrt.\nJroß- un Kleinboochshtabe maache ene Ungerscheid!\n<br />\nJetz muss De et noch ens versöke.\nUdder donn_[[Special:CreateAccount|ene neue Metmaacher aanmelde]].",
+       "nosuchuser": "Dä Metmaacher-Name „$1“ wohr verkihrt.\nJrohß- un Kleinbohchschtahbe maache ene Ongerscheid!\nSchrihv en eeschtesch, udder donn_[[Special:CreateAccount|ene neue Metmaacher aanmälde]].",
        "nosuchusershort": "Dä Metmaacher Name „$1“ wor verkihrt. Jetz muss De et noch ens versöke.",
        "nouserspecified": "Dat jeiht nit als ene Metmaacher Name",
        "login-userblocked": "Heh dä Kääl es jesperrt. Enlogge verbodde.",
        "botpasswords-updated-body": "Dat Bot-Paßwoot för dä Bot „$1“ {{GENDER:$2|vum|vum|vumm Metmaacher|vun dä|vum}} „$2“ wood veränndert.",
        "botpasswords-deleted-title": "Dat Bot-Paßwood es fott",
        "botpasswords-deleted-body": "Dat Bot-Paßwoot för dä Bot „$1“ {{GENDER:$2|vum|vum|vumm Metmaacher|vun dä|vum}} „$2“ wood fott jeschmeße.",
+       "botpasswords-not-exist": "Dä Metmaacher „$1“ kät keijn Paßwoot „$2“ för ene Bot.",
        "resetpass_forbidden": "E Passwoot kann nit jeändert wääde.",
        "resetpass_forbidden-reason": "Paßwööter kam_mer nit änndere: $1",
        "resetpass-no-info": "Do mööts ad enjelogg sin, öm tiräk op di Sigg jonn ze dörve",
        "passwordreset-emailsent-capture": "En <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> met Aanjahbe zom neue Paßwoot för der Zohjang heh es verschek woode. Heh dronger kanns De se lässe.",
        "passwordreset-emailerror-capture": "En <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> met Aanjahbe zom neue Paßwoot för der Zohjang heh sullt verschek wääde, ävver dat Verscheke aan {{GENDER:$2|dä|dat|dä Metmaacher|de|dat}} $2 hät nit jeflup: $1",
        "passwordreset-invalideamil": "Dat es en onjöltejje Addräß fö de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i>",
+       "passwordreset-nodata": "Keine Metmaacher_Nahme un kein Adräß för de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> es aanjejovve woode.",
        "changeemail": "Donn en Adräß för de <i lang=\"en\">e-mail</i> ändere udder fott schmiiße",
        "changeemail-header": "Donn heh dat Fommulaa ußfölle, öm Ding Adräß för de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> ze ändere. Wann De en Adräß loß wähde wells, maach dat Fäld läddesch, ih dat De dat Fommolaa loß scheks.",
        "changeemail-passwordrequired": "Do moß Ding Paßwood enjävve, öm di Änderong ze beschtähteje.",
        "template-semiprotected": "(halfjeschöz - tabu för neu Metmaacher un ohne Enlogge)",
        "hiddencategories": "Di Sigg heh is en {{PLURAL:$1|dä verschtoche Saachjropp: |dä $1 verschtoche Saachjroppe: |keij verschtoche Saachjroppe dren.}}",
        "edittools": "<!-- Dä Täx heh zeisch et Wikki onger däm Täxfeld zom „Ändere/Beärbeijde“ un beim Täxfeld vum „Huhlade“ ann. -->",
+       "edittools-upload": "-",
        "nocreatetext": "Sigge neu aanläje es nor müjjelich, wann de [[Special:UserLogin|enjelogg]] bes. Der ohne kanns De ävver Sigge ändere, di ald doh sin.",
        "nocreate-loggedin": "Do häs nit dat Rääch, neu Sigge aanzelääje.",
        "sectioneditnotsupported-title": "Afschnedde Ändere is nit zohjelohße",
        "mergehistory-fail-bad-timestamp": "Dattom odder Zigg udder beeds sin nit jöltesch",
        "mergehistory-fail-invalid-source": "De Quällesigg es nit jöltesch",
        "mergehistory-fail-invalid-dest": "De Zihlsigg es nit jöltesch",
+       "mergehistory-fail-no-change": "Et sin kein verjange Väsjohne zesamme jelaat wohde. Doht de Parramehtere för Sigg un Zigg norr_ens pröhfe.",
        "mergehistory-fail-permission": "Kein Berääschtejong, de vörreje Väsjohne zesamme ze lähle.",
        "mergehistory-fail-self-merge": "De Quell-Sigg un de Ziel-Sigg sin deselve Sigg.",
        "mergehistory-fail-timestamps-overlap": "De Väjsohne vun de Quällesigg kumme övverkrüz udder noh de Väsjohne vun de Zihlsigg.",
        "mergehistory-comment": "„[[:$1]]“ zosamme jelaat met „[[:$2]]“ — $3",
        "mergehistory-same-destination": "De Quell-Sigg un de Ziel-Sigg dörve nit deselve Sigg sinn.",
        "mergehistory-reason": "Der Jrond:",
+       "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
        "mergelog": "Logbohch fum Sigge zesamme Lähje",
        "revertmerge": "Dat Zosammelääje widder retuhr maache",
        "mergelogpagetext": "Dat heh es dat Logbohch fun de zesammejelaate Väsjohne fun Sigge",
        "youremail": "E-Mail *",
        "username": "{{GENDER:$1|Metmaacher|Metmaacherėnne|Metmaacher|Metmaacherėnne|Metmaacher}} Name:",
        "prefs-memberingroups": "{{GENDER:$2|Bes}} en {{PLURAL:$1|de Metmaacherjrupp:|$1 Metmaacherjruppe:|keijn Metmaacherjruppe.}}",
+       "prefs-memberingroups-type": "$1",
        "prefs-registration": "Aanjemäldt zigg",
        "prefs-registration-date-time": "dem $2 öm $3 Uhr",
        "yourrealname": "Dinge richtije Nahme *",
        "saveusergroups": "Donn {{GENDER:$1|däm|dem|däm Metmaacher|dä|däm}} [[User:$1|$1]] {{GENDER:$1|sing|singe|sing|ier|sing}} Jroppe faßhalle",
        "userrights-groupsmember": "Dä Metmaacher es en {{PLURAL:$1|dä Jropp:|dä Jroppe:|keine Jropp.}}",
        "userrights-groupsmember-auto": "Dä Metmaacher es automattesch en {{PLURAL:$1|dä Jropp:|dä Jroppe:|keine Jropp.}}",
+       "userrights-groupsmember-type": "$1",
        "userrights-groups-help": "Do kanns de Jroppe för dä Metmaacher heh änndere, ävver opjepaß:\n* E Käßje met Höksche bedüg, dat dä Metmaacher en dä Jropp es.\n* E Käßje ohne Höksche bedüg, dat dä Metmaacher nit en dä Jropp es.\n* E Käßje met Stähnsche donävve bedüg, dat De dat Rääsch zwa ändere, ävver de Änderong nit mih zeröck nämme kanns.",
        "userrights-reason": "Aanlaß odder Jrund:",
        "userrights-no-interwiki": "Do häs nit dat Rääsch, Metmaacher ier Rääschte in ander Wikis ze ändere.",
        "grant-patrol": "Änderonge aan Sigge nohkike",
        "grant-protect": "Sigge schöze un der Schoz wider ophävve",
        "grant-rollback": "Änderonge aan Sigge retuhr maache",
-       "grant-sendemail": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mails</i> aan ander Metmaacher schecke",
-       "grant-uploadeditmovefile": "Datteije uhlahde, ußtuusche un ömbenänne",
-       "grant-uploadfile": "Neu datteije huhlahde",
+       "grant-sendemail": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mails</i> aan annder Metmaacher schecke",
+       "grant-uploadeditmovefile": "Datteije huhlahde, ußtuusche un ömbenänne",
+       "grant-uploadfile": "Neu Datteije huhlahde",
        "grant-basic": "Jrondlähje Rääsch",
-       "grant-viewdeleted": "Fottjeschmeße Dahte un Sigge belohre",
-       "grant-viewmywatchlist": "De eije Oppaßleß ze belooere",
+       "grant-viewdeleted": "Fottjeschmeße Dahteije un Sigge belohre",
+       "grant-viewmywatchlist": "De eije Oppaßleß ze belohre",
        "newuserlogpage": "Logbohch för neu Metmaachere",
        "newuserlogpagetext": "He sin de Metmaacher opjelėßß, di sesh nöü aanjemäldt han.",
        "rightslog": "Logbohch för Änderonge aan Metmaacher-Rääschde",
        "rc_categories_any": "Öhndseijne vun dä aanjejovve Saachjroppe",
        "rc-change-size": "$1 {{PLURAL:$1|Byte|Bytes}}",
        "rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes|Bytes}} noh dem Ändere",
-       "newsectionsummary": "Neu Avschnet /* $1 */",
+       "newsectionsummary": "Neuje Afschnet /* $1 */",
        "rc-enhanced-expand": "Einzelheite aanzeije",
        "rc-enhanced-hide": "Einzelheite versteiche",
        "rc-old-title": "ojinaal als „$1“ aanjelaat",
        "uploaded-hostile-svg": "Mer han onseescher <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Cascading Style Sheet\">CSS</i>-Befähle en enem „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">style</code>“-Ellemänt vun dä huhjelahde <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge.",
        "uploaded-event-handler-on-svg": "Projramme för Ä'eijschneße ze behanndelle „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1=\"$2\"&gt;</code>“ ennzesäze es en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Datteije verbodde.",
        "uploaded-href-attribute-svg": "En <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Datteije darrev övver <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">href</code> blohß op <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"HyperText Transfer Protocol\">HTTP://</i> udder <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"HyperText Transfer Protocol Secure - HTTP övver SSL - HTTP övver TSL\">HTTPS://</i> verlenk wähde. Heh es ävver <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code> dren.",
-       "uploaded-href-unsafe-target-svg": "Mer han ene „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">href</code>“-Befähl obb e onseescher Zihl „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>“ en dä huhjelahde <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge.",
+       "uploaded-href-unsafe-target-svg": "Mer han ene „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">href</code>“-Befähl obb e onseescher Zihl mem <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Identifier\">URI</i> „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>“ en dä huhjelahde <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge.",
        "uploaded-animate-svg": "Mer han dä Befähl „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">animate</code>“ en dä huhjelahde \n<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge, dä ene „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">href</code>“-Befähl verändere künnt övver de „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">from</code>“-Eijeschaff „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>“.",
        "uploaded-setting-event-handler-svg": "Ed es verbodde, Projramme för Ä'eijschneße ze behanndelle ennzesäze, un de Datteije, di dat donn, wähde jeschpächt. Mer han „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>“ en dä huhjelahde <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge.",
        "uploaded-setting-href-svg": "Dä Befähl „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">set</code>“ för de „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">href</code>“-Eijeschaff vun övverjeohdente Ällemänt ze säze es jeschpächt.",
        "uploadstash-badtoken": "Dat ze donn hät nit jeflupp. Velleich wohre Ding Daate zom Deil verschött jejange udder afjeloufe. Versöhg et nor_rens.",
        "uploadstash-errclear": "Mer kunnte de Dateie nit fottschmieße.",
        "uploadstash-refresh": "De Leß met de Dateie op ene neue Shtand bränge",
+       "uploadstash-thumbnail": "et Minni-Belldsche aanlohre",
        "invalid-chunk-offset": "Ene onjöltijje Aanfangspungk för dä Rötsch",
        "img-auth-accessdenied": "Keine Zohjang",
        "img-auth-nopathinfo": "De <code xml:lang=\"en\" lang=\"en\" dir=\"rtl\">PATH_INFO</code> fäält.\nDä Webßööver es nit doför ennjerescht, di Ennfommazjuhn wigger ze jävve.\nHä künnd_op <code xml:lang=\"en\" lang=\"en\" dir=\"rtl\">CGI</code> opjebout sin, un dröm <code xml:lang=\"en\" lang=\"en\" dir=\"rtl\">img_auth</code> nit ongschtöze künne. Loor em [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization Handbohch] noh, wat domed es.",
        "apisandbox-jsonly": "Der ohne JavaSkrepp kam_mer de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> för zom erömprobehre nit bruche.",
        "apisandbox-api-disabled": "Dat <i lang=\"en\">API</i> es en heh dämm Wiki afjeschalldt.",
        "apisandbox-intro": "Op heh dä Sigg kanns De met dä <strong><i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> vum MehdijaWikki singem Wäbdehns</strong> eröm schpelle.\nBeloor Der de Einzelheijte, un wi di jebruch weed, op dä iere [[mw:API:Main_page Sigg met de Verklieronge]].\nE Beischpell: [https://www.mediawiki.org/wiki/API#A_simple_example De Houpsigg holle].\nSöhk ene {{int:Apisb-label-action}} uß, öm mih Beischpelle aanjezeisch ze krijje.\nOch wann dat heh nor zom Ußprobehre es, kann dat, wat De heh mähß, et Wikki veränndere.",
-       "apisandbox-unfullscreen": "Sigg aanzeije",
+       "apisandbox-fullscreen": "Om jannze Scherrem zeije",
+       "apisandbox-unfullscreen": "De Sigg nommahl aanzeije",
        "apisandbox-submit": "Lohß jonn!",
        "apisandbox-reset": "Läddesch maache",
        "apisandbox-retry": "Norr_ens versöhke",
+       "apisandbox-loading": "Ben de Ennfommazjuhne för et Moduhl „$1“ vun de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> aam lahde&nbsp;&hellip;",
        "apisandbox-helpurls": "Lengks för Hölp",
        "apisandbox-examples": "Bäijshpelle",
        "apisandbox-dynamic-parameters": "Zohsäzlejje Parrameetere",
        "mw-widgets-dateinput-no-date": "Kein Dattom es ußjewählt",
        "mw-widgets-titleinput-description-new-page": "di Sigg jidd_et noch nit",
        "mw-widgets-titleinput-description-redirect": "ömleijde op „$1“",
-       "api-error-blacklisted": "Söhk Der ene anndere Nahme uß, dä mih drövver säht.",
        "randomrootpage": "Zofällige Aanfangs-Sigg",
+       "log-action-filter-rights": "De Zoot Ännderong aan de Rääschte:",
+       "log-action-filter-suppress": "De Zoot Ongerdrökong:",
        "log-action-filter-all": "Alle",
        "log-action-filter-block-block": "Schpärre",
        "log-action-filter-block-unblock": "Sperr ophävve",
index 93a0039..ebee06b 100644 (file)
        "showingresults": "{{PLURAL:$1|Encamek|'''$1''' encam}}, bi #'''$2''' dest pê dike.",
        "search-nonefound": "Ti rûpelên wek ya daxwazkirî nînin.",
        "powersearch-legend": "Lêgerîna pêşketî",
-       "powersearch-ns": "Di valahiya navan de lêbigere:",
+       "powersearch-ns": "Di valahiya navan de lê bigere:",
        "powersearch-togglelabel": "Kontrol bike:",
        "powersearch-toggleall": "Hemû",
        "powersearch-togglenone": "Tune",
        "pageinfo-category-pages": "Hejmara rûpelan",
        "pageinfo-category-subcats": "Hejmara binkategoriyan",
        "pageinfo-category-files": "Hejmara dosyeyan",
-       "markaspatrolleddiff": "Wek serrastkirî nîşan bide",
-       "markaspatrolledtext": "Vê rûpelê wek serrastkirî nîşan bide",
-       "markedaspatrolled": "Wek serrastkirî tê nîşandan",
+       "markaspatrolleddiff": "Wek sererastkirî nîşan bide",
+       "markaspatrolledtext": "Vê rûpelê wek sererastkirî nîşan bide",
+       "markedaspatrolled": "Wek sererastkirî tê nîşandan",
        "markedaspatrolledtext": "Guherandina rûpelê wek serrastkirî tê nîşandan.",
        "patrol-log-page": "Têketina kontrolkirinê",
        "deletedrevision": "Guhertoya berê $1 hate jêbirin.",
index 45bf74a..1b1e725 100644 (file)
        "hidden-category-category": "Verstoppt Kategorien",
        "category-subcat-count": "Dës Kategorie huet {{PLURAL:$2|nëmmen dës Ënnerkategorie.|dës {{PLURAL:$1|Ënnerkategorie|$1 Ënnerkategorien}}, vu(n) $2 am Ganzen.}}",
        "category-subcat-count-limited": "Dës Kategorie huet dës {{PLURAL:$1|Ënnerkategorie|$1 Ënnerkategorien}}.",
-       "category-article-count": "An dëser Kategorie {{PLURAL:$2|ass just dës Säit.|{{PLURAL:$1|ass just dës Säit|si(nn) $1 Säiten}}, vu(n) $2 am Ganzen.}}",
+       "category-article-count": "An dëser Kategorie {{PLURAL:$2|ass just dës Säit.|{{PLURAL:$1|ass just dës Säit|sinn dës $1 Säiten}}, vu(n) $2 am Ganzen.}}",
        "category-article-count-limited": "Dës {{PLURAL:$1|Säit ass|$1 Säite sinn}} an dëser Kategorie.",
        "category-file-count": "{{PLURAL:$2|Just dëse Fichier ass an dëser Kategorie.|{{PLURAL:$1|Just dëse Fichier ass|Dës $1 Fichiere sinn}} an dëser Kategorie, vu(n) $2 am Ganzen.}}",
        "category-file-count-limited": "{{PLURAL:$1|Dëse Fichier ass|Dës $1 Fichiere sinn}} an dëser Kategorie.",
        "password-change-forbidden": "Dir däerft op dëser Wiki Passwierder net änneren.",
        "externaldberror": "Entweder ass e Feeler bei der externer Authentifizéierung geschitt, oder Dir däerft Ären externe Benotzerkont net aktualiséieren.",
        "login": "Aloggen",
+       "login-security": "Iwwerpréift Är Idnetitéit",
        "nav-login-createaccount": "Aloggen / Benotzerkont uleeën",
        "userlogin": "Aloggen / Benotzerkont uleeën",
        "userloginnocreate": "Umellen",
        "createacct-reason-ph": "Fir wat Dir een anere Benotzerkonnt uleet",
        "createacct-submit": "Äre Benotzerkont uleeën",
        "createacct-another-submit": "Benotzerkont uleeën",
+       "createacct-continue-submit": "Virufuere mam Uleeë vum Benotzerkont",
+       "createacct-another-continue-submit": "Virufuere mam Uleeë vum Benotzerkont",
        "createacct-benefit-heading": "{{SITENAME}} gëtt vu Leit wéi Iech gemaach.",
        "createacct-benefit-body1": "{{PLURAL:$1|Ännerung|Ännerungen}}",
        "createacct-benefit-body2": "{{PLURAL:$1|Säit|Säiten}}",
        "createacct-another-realname-tip": "De richtegen Numm ass fakultativ.\n\nWann Dir en ugitt, gëtt e benotzt fir d'Benotzerattributiounen fir Är Aarbecht zouzeuerdnen.",
        "pt-login": "Aloggen",
        "pt-login-button": "Aloggen",
+       "pt-login-continue-button": "Virufuere mam Aloggen",
        "pt-createaccount": "Benotzerkont opmaachen",
        "pt-userlogout": "Ausloggen",
        "php-mail-error-unknown": "Onbekannte Feeler an der PHP-Mail-Funktioun",
        "passwordreset-emailsent-capture": "Eng Mail fir d'Passwuert zréckzesetze gouf geschéckt, Dir gesitt se hei drënner.",
        "passwordreset-emailerror-capture": "Eng Mail fir d'Passwuert zréckzesetze gouf geschéckt, Dir gesitt se hei drënner, awer de {{GENDER:$2|Benotzer}} konnt se net kréien: $1",
        "passwordreset-invalideamil": "Net-valabel E-Mail-Adress",
+       "passwordreset-nodata": "Et gouf weder e Benotzernumm nach e Passwuert uginn",
        "changeemail": "E-Mail-Adress änneren oder ewechhuelen",
        "changeemail-header": "Fëllt dëse Formulaire aus fir Är E-Mailadress z'änneren.  Wann Dir d'Verbindung tëscht Ärer E-Mailadress an Ärem Benotzerkont ewechhuele wëllt, da loosst d'Feld e-Mailadress eidel wann Dir de Formulaire späichert.",
        "changeemail-passwordrequired": "Dir musst Äert Passwuert agi fir dës Ännerung ze konfirméieren.",
        "showpreview": "Kucken ouni ofzespäicheren",
        "showdiff": "Ännerunge weisen",
        "blankarticle": "<strong>Opgepasst:</strong> D'Säit déi Dir uleet ass eidel.\nWann Dir nach eng Kéier op \"{{int:savearticle}}\" klickt, da gëtt d'Säit ugeluecht.",
-       "anoneditwarning": "<strong>Opgepasst:</strong> Dir sidd net ageloggt. Dowéinst gëtt amplaz vun engem Benotzernumm Är IP Adress ëffentlech gewise wann Dir Ännerunge maacht. Wann Dir <strong>[$1 Iech aloggt]</strong> oder <strong>[$2 e Bnotzerkont opmaachen]</strong>, Är Ännerunge ginn dann Ärem Benotzerkont zougedeelt, genee wéi aner Avantagen.",
+       "anoneditwarning": "<strong>Opgepasst:</strong> Dir sidd net ageloggt. Dowéinst gëtt amplaz vun engem Benotzernumm Är IP Adress ëffentlech gewise wann Dir Ännerunge maacht. Wann Dir <strong>[$1 Iech aloggt]</strong> oder <strong>[$2 e Benotzerkont opmaachen]</strong>, Är Ännerunge ginn dann Ärem Benotzerkont zougedeelt, genee wéi aner Avantagen.",
        "anonpreviewwarning": "''Dir sidd net ageloggt. Wann Dir ofspäichert gëtt Är IP-Adress an der Lëscht vun de Versioune vun dëser Säit enregistréiert.''",
        "missingsummary": "'''Erënnerung:''' Dir hutt kee Resumé aginn.\nWann Dir nacheemol op \"{{int:savearticle}}\" klickt, gëtt Är Ännerung ouni Resumé ofgespäichert.",
        "selfredirect": "<strong>Opgepasst:</strong> Dir maacht eng Viruleedung vun dëser Aäit op sech selwer.\n\nEt ka sinn datt Dir déi falsch Zilsäit fir d'Viruleedung aginn hutt oder datt Dir déi falsch Säit ännert.\n\nWann Dir nach eng Kéier op \"{{int:savearticle}}\" klickt, da gëtt d'Viruleedung trotzdem ugeluecht.",
        "previewnote": "'''Denkt drun datt dëst nëmmen eng net gespäichert Versioun ass.'''\nÄr Ännerunge sinn nach net gespäichert!",
        "continue-editing": "Gitt weider an de Beräich fir z'änneren",
        "previewconflict": "Dir gesitt an dem ieweschten Textfeld wéi den Text ausgesi wäert, wann Dir späichert.",
-       "session_fail_preview": "<strong>Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.</strong>\nVersicht et w.e.g. nach eng Kéier.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen.",
+       "session_fail_preview": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\nDir gouft eventuell ausgeloggt. <strong>Iwwerpréift w.e.g. ob Dir nach ageloggt sidd a probéiert nach eng Kéier</strong>.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen an iwwerpréift datt Äre Browser Cookië vun dësem Site  akzeptéiert.",
        "session_fail_preview_html": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.</strong>\n\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen a vergewëssert Iech datt Äre Browser d^Späichere vu Cookieë vun dësem Site zouléisst.",
        "token_suffix_mismatch": "'''Är Ännerung gouf refuséiert, well Äre Browser Zeechen am Ännerungs-Identifiant verännert huet.'''\nD'Ännerung gouf refuséiert, fir ze verhënneren datt den Text op der Säit onliesbar gëtt.\nDëst geschitt heiansdo wann Dir en anonyme Proxy-Service um Internet benotzt.",
        "edit_form_incomplete": "'''En Deel vum Ännerungsformulaire koum net um Server un; iwwerpréift w.e.g ob Är Ännerunge komplett sinn a probéiert nach emol.'''",
        "mergehistory-empty": "Et kënne keng Versioune zesummegeluecht ginn.",
        "mergehistory-done": "{{PLURAL:$3|1 Versioun gouf|$3 Versioune goufe}} vu(n) $1 op [[:$2]] zesummegeluecht.",
        "mergehistory-fail": "Versiounszesummeleeung war net méiglech, kuckt w.e.g. d'Säiten an d'Zäit-Parameter no.",
+       "mergehistory-fail-bad-timestamp": "Zäitstempel ass net valabel.",
+       "mergehistory-fail-invalid-source": "Quellsäit ass net valabel.",
+       "mergehistory-fail-invalid-dest": "Zilsäit ass net valabel.",
        "mergehistory-fail-toobig": "D'zesummeleeë vun der Lëscht vun de Versioune konnt net gemaach ginn well méi wéi d'Limite vun $1 {{PLURAL:$1|Versioun|Versioune}} geréckelt géife ginn",
        "mergehistory-no-source": "Originalsäit \"$1\" gëtt et net.",
        "mergehistory-no-destination": "Zilsäit \"$1\" gëtt et net.",
        "right-unwatchedpages": "Lëscht vun den net iwwerwaachte Säite weisen",
        "right-mergehistory": "Zesummeféierung vum Historique vun de Versioune vu Säiten",
        "right-userrights": "All Benotzerrechter änneren",
-       "right-userrights-interwiki": "Benotzerrechter vu Benotzer op anere Wiki-Siten änneren",
+       "right-userrights-interwiki": "Benotzerrechter vu Benotzer op anere Wiki-Sitten änneren",
        "right-siteadmin": "Datebank spären an d'Spär ophiewen",
        "right-override-export-depth": "Säiten exportéieren inklusiv de verlinkte Säite bis zu enger Déift vu 5",
        "right-sendemail": "Anere Benotzer E-Maile schécken",
        "upload-too-many-redirects": "Et waren zevill Viruleedungen fir d'URL do",
        "upload-http-error": "Et ass en HTTP-Feeler geschitt: $1",
        "upload-copy-upload-invalid-domain": "Vun dësem Domain ass d'Eropluede vu Kopien net méiglech.",
+       "upload-dialog-disabled": "D'Eropluede vu Fichieren mat dësem Dialog ass op dëser Wiki desaktivéiert.",
        "upload-dialog-title": "Fichier eroplueden",
        "upload-dialog-button-cancel": "Ofbriechen",
        "upload-dialog-button-done": "Fäerdeg",
        "apisandbox-dynamic-parameters": "Zousätzlech Parameteren",
        "apisandbox-dynamic-parameters-add-label": "Parameter derbäisetzen:",
        "apisandbox-dynamic-parameters-add-placeholder": "Numm vum Parameter",
+       "apisandbox-dynamic-error-exists": "Et gëtt schonn e Parameter mam Numm \"$1\".",
        "apisandbox-deprecated-parameters": "Vereelst Parameter",
        "apisandbox-submit-invalid-fields-title": "E puer Felder sinn net valabel.",
        "apisandbox-results": "Resultater",
        "apisandbox-request-url-label": "URL fir Ufroen:",
        "apisandbox-request-time": "Dauer vun der Ufro: {{PLURAL:$1|$1 ms}}",
        "apisandbox-alert-page": "Felder op dëser Säit sinn net valabel.",
+       "apisandbox-alert-field": "De wäert vun dësem Feld ass net valabel.",
        "booksources": "Bicherreferenzen",
        "booksources-search-legend": "No Bicherreferenze sichen",
        "booksources-search": "Sichen",
        "tooltip-pt-preferences": "{{GENDER:|Är}} Astellungen",
        "tooltip-pt-watchlist": "Lëscht vu Säiten, bei deenen Dir op Ännerungen oppasst",
        "tooltip-pt-mycontris": "Lëscht vun {{GENDER:|Äre}} Kontributiounen",
+       "tooltip-pt-anoncontribs": "Eng Lëscht vun Ännerungen déi vun dëser IP-Adress aus gemaach goufen",
        "tooltip-pt-login": "Sech umelle gëtt gäre gesinn, Dir musst et awer net maachen.",
        "tooltip-pt-logout": "Ofmellen",
        "tooltip-pt-createaccount": "Et gëtt Iech geroden e Benotzerkont unzeleeën an Iech anzeloggen; dat ass awer net obligatoresch",
        "mw-widgets-dateinput-placeholder-month": "JJJJ-MM",
        "mw-widgets-titleinput-description-new-page": "Säit gëtt et nach net",
        "mw-widgets-titleinput-description-redirect": "viruleeden op $1",
-       "api-error-blacklisted": "Sicht w.e.g. en aneren Titel, dee méi iwwer de Sujet ausseet.",
        "sessionprovider-generic": "$1-Sessiounen",
        "randomrootpage": "Zoufalls-Stammsäit",
        "log-action-filter-block": "Typ vun der Spär:",
index de75f5e..bdb0a1d 100644 (file)
@@ -30,6 +30,7 @@
        "tog-watchdefault": "Azonzi e paggine e i files che modiffico a-i mæ sotta oservaçion",
        "tog-watchmoves": "Azonzi e paggine e i file che mescio a-i mæ sotta oservaçion",
        "tog-watchdeletion": "Azonzi e paggine e i files che scancello a-i mæ sotta oservaçion",
+       "tog-watchuploads": "Azonzi i noeuvi file che metto in osservaçion",
        "tog-watchrollback": "Azonzi a-i sotta osservassion e paggine dovve ho fæto un rollback",
        "tog-minordefault": "Indica de longo comme menô e modiffiche",
        "tog-previewontop": "Veddi l'anteprimma de d'äto a-o spaçio pe cangiâ",
        "databaseerror-query": "Query: $1",
        "databaseerror-function": "Fonsion: $1",
        "databaseerror-error": "Errô: $1",
+       "transaction-duration-limit-exceeded": "Pe evitâ un ato ritardo de replica, questa opiaçion a l'è stæta interotta perché a duata do tempo de scrittua ($1) a l'ha superou o limmite de $2 {{PLURAL:$2|segondo|segondi}}.\nSe t'ê aproeuvo a cangiâ tante cose inte'na votta sola, proeuva invece a cangiâ poche cose in tante votte.",
        "laggedslavemode": "'''Attension:''' a paggina a porriæ no riportâ i aggiornamenti ciù reçenti.",
        "readonly": "Database bloccòu",
        "enterlockreason": "Scrivi o motivo do blocco, e 'na stimma de quande o saiâ rimosso",
        "mypreferencesprotected": "No ti g'hæ o permisso pe modificâ e teu preferense.",
        "ns-specialprotected": "No se pœu modificâ e paggine speciali",
        "titleprotected": "A creaçion de 'na paggina con sto tittolo a l'è stæta bloccâ da [[User:$1|$1]].\nA raxon a l'è: <em>$2</em>.",
-       "filereadonlyerror": "N'ho posciuo modificâ o file \"$1\" perché o repository de file \"$2\" o l'è in modalitæ de sola lettua.\n\nL'amministratô ch'o l'ha bloccòu o l'ha fornio sta motivaçion: \"$3\".",
+       "filereadonlyerror": "N'ho posciuo modificâ o file \"$1\" perché o repository de file \"$2\" o l'è in modalitæ de sola lettua.\n\nL'amministratô de scistema ch'o l'ha bloccòu o l'ha fornio sta motivaçion: \"$3\".",
        "invalidtitle-knownnamespace": "Tittolo non vallido con namespace \"$2\" e testo \"$3\"",
        "invalidtitle-unknownnamespace": "Tittolo non vallido con namespace sconosciuo \"$1\" e testo \"$2\"",
        "exception-nologin": "No t'ê introu",
        "virus-scanfailed": "scansion fallia (codice $1)",
        "virus-unknownscanner": "antivirus sconosciuo:",
        "logouttext": "'''Sciortîa effettuâ.'''\n\nDanni a mente che gh'è de paggine che porrieivan continuâ a pai comme se a sciortîa a no foise avegnua, pe scin che no ti nettezzi a cache do to navegatô.",
+       "cannotlogoutnow-title": "Aoa no se poeu sciortî",
+       "cannotlogoutnow-text": "Quande s'adoeuvia $1 no se poeu sciortî.",
        "welcomeuser": "Benvegnuo, $1!",
        "welcomecreation-msg": "L'utensa a l'è stæta creâ correttamente.\nSe ti veu ti peu personalizzâ e [[Special:Preferences|preferençe de {{SITENAME}}]].",
        "yourname": "Nomme",
        "remembermypassword": "Aregòrda a mæ login in sto navegatô (pe in mascimo de $1 {{PLURAL:$1|giórno|giórni}})",
        "userlogin-remembermypassword": "Mantegnime collegou",
        "userlogin-signwithsecure": "Adoeuvia una conescion segua",
+       "cannotloginnow-title": "Aoa no se poeu intrâ",
+       "cannotloginnow-text": "Quande s'adoeuvia $1 no se poeu intrâ.",
        "yourdomainname": "Indirisso do scito:",
        "password-change-forbidden": "No ti peu cangiâ poula segretta in questa wiki.",
        "externaldberror": "Gh'è stæto un aro co-ol server de autenticaçion esterno, oppû no ti g'hæ i aotorizzaçioin pe aggiornâ o to accesso esterno.",
        "login": "Intra",
+       "login-security": "Veifica a to identitæ",
        "nav-login-createaccount": "Intra / Registrate",
        "userlogin": "Intra / Registrite",
        "userloginnocreate": "Intra",
        "userlogin-resetpassword-link": "T'hæ miga ascordou a teu poula segretta?",
        "userlogin-helplink2": "Agiutto pe intrâ",
        "userlogin-loggedin": "Ti t'ê zà connesso comme {{GENDER:$1|$1}}.\nUsa o formulaio sottostante pe accede comme 'n atro utente.",
+       "userlogin-reauth": "Ti g'hæ da intrâ 'n'atra votta pe veificâ che ti t'ê {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Crea 'n atra utensa",
        "createacct-emailrequired": "Addresso e-mail:",
        "createacct-emailoptional": "Adresso email (opsionale)",
        "createacct-email-ph": "Scrivi o teu adresso email",
        "createacct-another-email-ph": "Scrivi o teu adresso email",
        "createaccountmail": "Doeuvia una password temporanea abrettio e mandila a l'adresso de posta elettronica speçificou",
+       "createaccountmail-help": "O poeu ese doeuviou pe creâ un'utensa pe 'n'atra person-a sensa doveine conosce a password.",
        "createacct-realname": "Nomme reale (opçionâ)",
        "createaccountreason": "Raxon:",
        "createacct-reason": "Raxon",
        "createacct-reason-ph": "Perché t'ê apreuvo a creâ un'atra utensa",
+       "createacct-reason-help": "Messaggio vixualizou into registro da creaçion de l'utença",
        "createacct-submit": "Crea a to utensa",
        "createacct-another-submit": "Crea utensa",
+       "createacct-continue-submit": "Continnoa a creaçion de l'utença",
+       "createacct-another-continue-submit": "Continnoa a creaçion de l'utença",
        "createacct-benefit-heading": "{{SITENAME}} o l'è realizzou da de gente comme ti.",
        "createacct-benefit-body1": "{{PLURAL:$1|modiffica|modiffiche}}",
        "createacct-benefit-body2": "{{PLURAL:$1|paggina|paggine}}",
        "nocookiesnew": "L'utensa a l'è stæta creâ, ma ti no t'ê intròu. {{SITENAME}} o deuvia i cookie pe lasciâ intrâ i utenti e ti ti ghe l'hæ disattivæ.\nRipreuva a intrâ co-o to nomme utente e poula segretta apen-a creæ doppo avei attivòu i cookie.",
        "nocookieslogin": "Pe intrâ in {{SITENAME}} bezeugna aveighe i cookie attivæ. Ti ti ghe l'hæ disattivæ. Pe piaxei attîvili e preuva torna a intrâ.",
        "nocookiesfornew": "L'utensa a no l'è stæta creâ, perché n'emmo posciuo confermâ a so sorgente.\nAsseguite d'avei attivòu i cookie, recarrega sta paggina e ripreuva.",
+       "createacct-loginerror": "L'utença a l'è stæta creaa correttamente, ma no l'è stæto poscibbile fate accede in moddo aotomattico. Procedi co l'[[Special:UserLogin|accesso manoâ]].",
        "noname": "O nomme d'ûtente o l'è sballiòu.",
        "loginsuccesstitle": "Accesso effettuòu",
        "loginsuccess": "'''O collegamento a-o server de {{SITENAME}} co-o nomme d'ûtente \"$1\" o l'è attivo.'''",
        "noemail": "No gh'è nisciûn indirisso e-mail registròu pe l'ûtente \"$1\".",
        "noemailcreate": "Ti devi dâ un addresso e-mail vallido.",
        "passwordsent": "Ûnn-a nêuva paròlla d'ordine a l'è stæta inviâa a l'indirisso e-mail registròu pe l'ûtente \"$1\".\nPe piaxei, fa 'n accesso appenn-a ti a ghe reçeivi.",
-       "blocked-mailpassword": "O teu addresso IP o l'è bloccòu, e pe sta raxon non se peu usâ a funsion de recuppero da pòula segretta, pe prevegnî di abuxi.",
+       "blocked-mailpassword": "O teu addresso IP o l'è bloccòu a-e modiffiche, pe prevegnî di abuxi non se peu doeuviâ a fonçion de recuppero da pòula segretta da queseto addresso IP.",
        "eauthentsent": "Un messaggio e-mail de conferma o l'è stæto inviòu a l'addresso indicòu.\nPe abilitâ l'invîo de messaggi e-mail pe quest'utensa, se deve seguî e instrussioin indicæ, pe confermâ che ti t'ê o legittimo propietâio de l'utensa.",
        "throttled-mailpassword": "Un'e-mail de reimpostassione da poula segretta a l'è zà stæta inviâ da meno de {{PLURAL:$1|1 oa|$1 oe}}.\nPe prevegnî di abuxi, a fonsion de reimpostassion da poula segretta a peu vese deuviâ solo che 'na votta ogni {{PLURAL:$1|oa|$1 oe}}.",
        "mailerror": "Errô inte l'invio do messaggio: $1",
        "createacct-another-realname-tip": "O nomme veo o l'è opçionâ.\nSe ti çerni de inseilo, o saiâ deuviòu pe attribuî a l'aotô a paternitæ di contengnui inviæ.",
        "pt-login": "Intra",
        "pt-login-button": "Intra",
+       "pt-login-continue-button": "Continoa l'accesso",
        "pt-createaccount": "Registrite",
        "pt-userlogout": "Sciorti",
        "php-mail-error-unknown": "Errô sconosciuo intaa funçion PHP mail()",
        "newpassword": "Neuva poula segretta",
        "retypenew": "Ripette a nêuva paròlla d'ordine:",
        "resetpass_submit": "Çerni a poula segretta e intra",
-       "changepassword-success": "O cangio de password o l'é anæto ben!",
+       "changepassword-success": "A to password a l'è stæta cangiâ!",
        "changepassword-throttled": "T'hæ çercòu de intrâ troppe votte tutt'assemme.\nPe piaxei aspeta $1 primma de provâ torna.",
+       "botpasswords": "Password bot",
+       "botpasswords-summary": "<em>Password bot</em> o consente l'accesso a un'utença tramite API sença doeuviâ e credençiæ d'accesso prinçipæ de l'utença. I driti utente disponibili quande s'è effettuou l'accesso co-ina password bot poeuan ese limitæ.\n\nSe no ti conosci o motivo pe-o quæ ti porriesci voeilo fâ, alloa foscia no ti doviesci fâlo. Nisciun doviæ mai domandâte de generâ un de questi e dapoeu dâlo a liatri.",
+       "botpasswords-disabled": "E password bot son disabilitæ.",
+       "botpasswords-no-central-id": "Pe doeuviâ una password bot, l'è necessaio accede a un'utença çentralizzâ.",
+       "botpasswords-existing": "Password bot in existença",
+       "botpasswords-createnew": "Crea una noeuva password bot",
+       "botpasswords-editexisting": "Modifica una password bot existente",
+       "botpasswords-label-appid": "Nomme bot:",
+       "botpasswords-label-create": "Crea",
+       "botpasswords-label-update": "Aggiorna",
+       "botpasswords-label-cancel": "Anulla",
+       "botpasswords-label-delete": "Scassa",
+       "botpasswords-label-resetpassword": "Reimposta a poula segretta",
+       "botpasswords-label-grants": "Assegnaçioin applicabile:",
+       "botpasswords-help-grants": "Ogni assegnaçion a dà accesso a-i driti utente elencæ che un'utença a g'ha zà. Amia a [[Special:ListGrants|tabella d'e assegnaçioin]] pe de ulteioî informaçioin.",
+       "botpasswords-label-restrictions": "Restriçioin d'utilizzo:",
+       "botpasswords-label-grants-column": "Assegnaçioin",
+       "botpasswords-bad-appid": "O nomme bot \"$1\" o no l'è vallido.",
+       "botpasswords-insert-failed": "Imposcibile azonze o nomme bot \"$1\". O l'è za stæto azonto?",
+       "botpasswords-update-failed": "Imposcibile aggiornâ o nomme bot \"$1\". O l'è stæto scassou?",
+       "botpasswords-created-title": "Password bot creâ",
+       "botpasswords-created-body": "A password pe-o bot de nomme \"$1\" de l'utente \"$2\" a l'è stæta creâ.",
+       "botpasswords-updated-title": "Password bot aggiornâ",
+       "botpasswords-updated-body": "A password pe-o bot de nomme \"$1\" de l'utente \"$2\" a l'è stæta aggiornâ.",
+       "botpasswords-deleted-title": "Password bot scassâ",
+       "botpasswords-deleted-body": "A password pe-o bot de nomme \"$1\" de l'utente \"$2\" a l'è stæta scassâ.",
+       "botpasswords-newpassword": "A noeuva password pe accede con <strong>$1</strong> a l'è <strong>$2</strong>. <em>Marchitelo pe rifeimento futuo.</em>",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider o no l'è disponibbile.",
+       "botpasswords-restriction-failed": "E restriçioin de password bot impediscian questo accesso.",
+       "botpasswords-invalid-name": "O nomme utente indicou o no conten o separatô pe-o password bot (\"$1\").",
+       "botpasswords-not-exist": "L'utente \"$1\" o no dispon-e de 'na password bot ciamâ \"$2\".",
        "resetpass_forbidden": "No l'é poscìbile cangiâ e paròlle segrétte",
+       "resetpass_forbidden-reason": "No l'é poscìbile cangiâ e paole segrette: $1",
        "resetpass-no-info": "Pe anâ direttamente a sta paggina, primma ti g'hæ da intrâ .",
        "resetpass-submit-loggedin": "Cangia a password",
        "resetpass-submit-cancel": "Anulla",
        "passwordreset-email": "Addresso e-mail:",
        "passwordreset-emailtitle": "Dettaggi account sciu {{SITENAME}}",
        "passwordreset-emailtext-ip": "Quarcun (probabilmente ti, con adresso IP $1) o l'ha domandòu l'invio de 'na neuva poula segretta per l'accesso a {{SITENAME}} ($4). {{PLURAL:$3|L'utente associòu|I utenti associæ}} a sto addresso e-mail son:\n\n$2\n\n{{PLURAL:$3|Questa poula segretta temporannia a descazziâ|Queste poule segrette temporannie descazzian}} doppo {{PLURAL:$5|un giorno|$5 giorni}}.\nTi doviesci accede e çerne una neuva poula segretta oua. \n\nSe no t'ê stæto ti a fâ a domanda, ò se ti t'hæ aregordòu a poula segretta originale e no ti veu ciù cangiâla, ti peu ignorâ sto messaggio e continuâ a deuviâ a teu vegia poula segretta.",
+       "passwordreset-emailtext-user": "L'utente $1 de {{SITENAME}} o l'ha domandou l'inandio de 'na noeuva password pe l'accesso a {{SITENAME}} ($4). {{PLURAL:$3|L'utente associou|I utenti associæ}} a questo indriçço email son:\n\n$2\n\n{{PLURAL:$3|Questa password temporannia a descazziâ|Queste password temporannie descazian}} doppo {{PLURAL:$5|un giorno|$5 giorni}}.\nTi doviesci accede e çerne una noeuva password aoa. \n\nSe no t'ê stæto ti a fâ a recesta, o se ti t'ê aregordou a password originâ e no ti voeu ciu cangiala, ti poeu ignorâ sto messaggio e continoâ a doeuviâ a to vegia password.",
        "passwordreset-emailelement": "Nomme utente: \n$1\n\nPoula segretta temporannia: \n$2",
-       "passwordreset-emailsentemail": "Se questo o l'è un addresso de posta elettronnica registròu pe-a teu utensa, alloa saiâ inviâ un'e-mail pe reimpostâ a poula segretta.",
+       "passwordreset-emailsentemail": "Se questo addresso de posta elettronnica o l'è associou a-a teu utença, alloa saiâ inviou un'e-mail pe rempostâ a poula segretta.",
+       "passwordreset-emailsentusername": "Se gh'è un adreçço de posta elettronica associou con questo nomme utente, alloa saiâ inviou una email pe rempostâ a password.",
        "passwordreset-emailsent-capture": "L'è stæto inviòu un'e-mail de reimpostaçion da poula segretta, o contegnuo o l'è riportòu chì appreuvo.",
        "passwordreset-emailerror-capture": "L'è stæto generòu un'e-mail de reimpostaçion da poula segretta, riportà chì appreuvo. L'invio {{GENDER:$2|a l'utente}} o no l'è ariêscîo: $1",
+       "passwordreset-emailsent-capture2": "L'email de rempostaçion da password {{PLURAL:$1|a l'è stæta inviâ|son stæte inviæ}}. {{PLURAL:$1|O nomme|L'elenco di nommi}} utente e password o l'è mostrou chì de sotta.",
+       "passwordreset-emailerror-capture2": "Invio de email {{GENDER:$2|a l'utente}} non ariescio: $1. {{PLURAL:$3|O nomme|L'elenco di nommi}} utente e password o l'è mostrou chì de sotta.",
+       "passwordreset-nocaller": "Un chi ciamma ti g'hæ da dâlo",
+       "passwordreset-nosuchcaller": "O ciamante o no l'existe: $1",
+       "passwordreset-ignored": "A reimpostaçion da password a no l'è stæta gestia. Foscia n'è stæto configuou nisciun provider ?",
+       "passwordreset-invalideamil": "Addresso e-mail non vallido",
+       "passwordreset-nodata": "No è stæto fornio ni un nomme utente ni un adreçço de posta elettronica",
        "changeemail": "Cangia o elimmina l'adresso e-mail",
        "changeemail-header": "Completa sto formulaio pe cangiâ o to adresso e-mail. Se ti veu rimeuve l'associaçion de quasesegge addresso e-mail da-a teu utensa, lascia io neuvo addresso e-mail veuo quande ti invii o formulaio.",
        "changeemail-passwordrequired": "Saiâ necessaio insei a poula segretta pe confermâ a modiffica.",
        "minoredit": "Cangiamento minô (m)",
        "watchthis": "Metti sotta oservaçion",
        "savearticle": "Sarva a pàgina",
+       "savechanges": "Sarva e modiffiche",
+       "publishpage": "Pubbrica a paggina",
+       "publishchanges": "Pubbrica e modiffiche",
        "preview": "Anteprìmma",
        "showpreview": "Veddi l'anteprimma",
        "showdiff": "Veddi i cangiamenti",
        "accmailtext": "Una poula segretta generâ abrettio pe [[User talk:$1|$1]] a l'è stæta mandâ a $2.\n\nSta poula segretta a peu ese cangiâ inta paggina pe ''[[Special:ChangePassword|cangiâ a poula segretta]]'' subbito doppo l'accesso.",
        "newarticle": "(Nêuvo)",
        "newarticletext": "Sto colegaménto o corisponde a 'na pàgina ch'a no l'existe ancon.\n\nSe se vêu creâ a pàgina òua, se pêu comensâ a scrive into spàçio chì sotta.\n(amia e [$1 paggine d'agiûtto] pe ciû informaçioìn).\n\nSe t'ê intròu chì pe sballio,  sciacca '''Inderê''' into navegatô.",
-       "anontalkpagetext": "----\n''Sta chì a l'è a paggina de discuscion de un utente anonnimo, ch'o no l'ha ancon creou un'utensa o comunque o no a doeuvia oua. Pe identificâlo l'è quindi necessaio doeuviâ o nummero do so adresso IP. I adresci IP poeuan però ese condivixi da ciù utenti. Se t'ê un utente anonimo e ti ritegni che i commenti inte sta pagina no se riferiscian a ti, [[Special:CreateAccount|crea una noeuva utensa]] o donque [[Special:UserLogin|intra con quella che ti g'hæ za]] pe evitâ de chì avanti de ese confuzo con di atri utenti anonnimi .''",
-       "noarticletext": "Po-u momento a pagina çercâ a l'è vêua. L'è poscibbile [[Special:Search/{{PAGENAME}}|çercâ 'sto tittolo]] inte âtre pagine do scîto opû [{{fullurl:{{FULLPAGENAME}}|action=edit}} cangiâ a pagina òua].",
+       "anontalkpagetext": "----\n<em>Sta chì a l'è a paggina de discuscion de un utente anonnimo, ch'o no l'ha ancon creou un'utensa o comunque o no a doeuvia oua.</em> Pe identificâlo l'è quindi necessaio doeuviâ o nummero do so adresso IP. I adresci IP poeuan però ese condivixi da ciù utenti. Se t'ê un utente anonnimo e ti ritegni che i commenti inte sta pagina no se riferiscian a ti, [[Special:CreateAccount|crea una noeuva utensa]] o donque [[Special:UserLogin|intra con quella che ti g'hæ za]] pe evitâ de chì avanti de ese confuzo con di atri utenti anonnimi .",
+       "noarticletext": "Po-u momento a pagina çercâ a l'è vêua. Ti poeu [[Special:Search/{{PAGENAME}}|çercâ sto tittolo]] inti atre pagine do scito, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} çercâ inti registri correlæ] oppû [{{fullurl:{{FULLPAGENAME}}|action=edit}} creâ questa pagina]</span>.",
        "noarticletext-nopermission": "Òua a pàgina çercâ a l'è vêua. L'è poscìbile [[Special:Search/{{PAGENAME}}|çercâ sto tìtolo]] inte di âtre pàgine do scîto o <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} çercâ inti registri corelæ]</span>, ma no ti gh'hæ i outorizzaçioin pe creâ sta paggina.",
        "missing-revision": "La verscion #$1 da paggina \"{{FULLPAGENAME}}\" a no l'esiste.\n\nQuesto succede solitamente se inta stoia ti sciacchi un vegio ingancio a una paggina scassâ.\n\nI dettaggi peuan ese attrovæ into [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de scançellaçioin].",
        "userpage-userdoesnotexist": "L'utensa \"$1\" a no corisponde a un utente registròu.\nTi veu davei creâ o modificâ sta paggina?",
        "previewnote": "'''Questa chì a l'è solo 'n'anteprimma; i cangiamenti no son ancon stæti sarvæ!'''",
        "continue-editing": "Vanni a l'area de modiffica",
        "previewconflict": "L'anteprimma a mostra o scrito presente inta casella de modiffica de d'ato coscì comme o l'apaiâ se ti çerni de sarvalo òua.",
-       "session_fail_preview": "'''N'emmo posciuo elaborâ a modiffica a caosa da pèrdia di dæti relativi a-a sescion.'''\nRitenta.\nSe-o problema o persciste, preuva a [[Special:UserLogout|sciortî]] e a intrâ torna.'''",
+       "session_fail_preview": "Spiaxenti. No è støto poscibile elaboâ a modifica perché son andæti persci i dæti relativi a-a sescion.\n\nFoscia t'ê stæto disconnesso. <strong>Verifica d'ese ancon collegou e riproeuva</strong>.\nSe o problema o persciste, ti poeu provâ a [[Special:UserLogout|scollegate]] e effettuâ un nuoeuvo accesso, controllando che o to browser o l'açette i cookie da questo scito.",
+       "session_fail_preview_html": "Spiaxenti. No è stæto poscibbile elaboâ a modifica perché son anæti persci i dæti relativi a-a sescion.\n\n<em>Scicomme {{SITENAME}} o g'ha de l'HTML sgroeuzzo attivou e gh'è stæto una perdia di dæti da sescion, l'anteprimma a l'è ascosa comme precaoçion contra i attacchi JavaScript.</em>\n\n<strong>Se se tratta de un normale tentativo d'anteprimma, riproeuva.</strong> \nSe o problema o persciste, ti poeu provâ a [[Special:UserLogout|scollegati]] e effettuâ un noeuvo accesso, controllando che o to browser o l'açette i cookie da questo scito.",
+       "token_suffix_mismatch": "'''A modiffica a no l'è stæta sarvâ perché o to client o l'ha mostrou de gestî in moddo errou i carattei de puntezatua into token associou a-a mæxima. Pe evitâ una poscibile corruçion do testo da pagina, l'è stæto refuou l'intrega modiffica. Questa scituaçion a poeu veificase, de votte, quande s'adoeuvia di serviççi de proxy anonnimi via web che presentan di bug.'''",
        "edit_form_incomplete": "'''De parte do formulaio de modiffica n'han razonto o server; controlla che e modiffiche seggian intatte e ripreuva.'''",
        "editing": "Modiffica de $1",
        "creating": "T'ê apreuvo a creâ $1",
        "editingold": "<strong>Attençion: t'ê apreuvo a modificâ una verscion non aggiornâ da paggina.</strong>\nSarvandola coscì, tutti i cangi fæti doppo sta verscion saian sorvescriti.",
        "yourdiff": "Differense",
        "copyrightwarning": "Nota: Tùtte e contribuçioìn a {{SITENAME}} van conscideræ comme rilasciæ drento a-i termini da licensa d'ûso $2 (veddi $1 pe savéine de ciù).\nSe no ti veu che i testi teu pêuan esse modificæ da quarchedùn sensa limitaçioìn, no mandâli a {{SITENAME}}.<br />\nInviando o testo ti diciâri, sott'a teu responsabilitæ, ch'o l'é stæto scrîto da ti personalmente oppure ch'o l'é stæto piggiòu da 'na fonte de pùbrico domìnio òu anàlogamente lìbea.<br />\n'''NO INVI MATERIÂLE COVERTO DA DRÎTI D'AUTÔ SENSA OUTORIZAÇION!'''",
+       "copyrightwarning2": "Pe piaxei tegni presente che tutti i contributi a {{SITENAME}} poeuan ese modificæ, alteræ ò scassæ da di atri contributoî.\nSe no ti voeu che se faççe ravaxo di to testi, alloa no stali manco a mette.<br />\nInviando o testo ti deciæi ascì, sotta a to responsabilitæ, ch'o l'è stæto scrito da ti personalmente oppù ch'o l'è stæto copiou da 'na fonte de pubbrico dominnio o scimilemente libera (vedi $1 pe dettaggi).\n'''No stanni a inviâ do mateiâ protetto da-o drito d'aotô sença aotorizzaçion!'''",
        "editpage-cannot-use-custom-model": "O modello do contegnuo de sta paggina o no peu ese modificòu.",
        "longpageerror": "'''Errô: o scrito inviou o l'è longo {{PLURAL:$1|1|$1}} kilobyte, ciu che-o mascimo consentio de ({{PLURAL:$2|1|$2}} kilobyte).'''\nNo se peu sarvâ.",
+       "readonlywarning": "<strong>Attençion</strong>: o database o l'è bloccou pe manutençion, no l'è momentaniamente poscibile sarvâ e modifiche effettuæ.\nPe no perdile, coppile in te'n file de testo e sarvilo in atteisa do sbrocco do database.\n\nL'amministratô de scistema ch'o l'ha misso l'abrocco o l'ha fornio questa spiegaçion: $1.",
        "protectedpagewarning": "'''Attençion: questa paggina a l'è stæta bloccâ de moddo che solo i utenti co-i privileggi d'amministratô possan modificala.'''\nL'urtimo elemento do registro o l'è riportou chì appreuvo pe referença:",
        "semiprotectedpagewarning": "'''Notta:''' Questa paggina a l'è stæta bloccä de moddo che solo i utenti registræ possan modificâla.\nL'urtimo elemento do registro o l'è riportou chì appreuvo pe referensa:",
        "cascadeprotectedwarning": "'''Attençion:''' Questa paggina a l'è stæta bloccâ de moddo che solo i utenti co-i privileggi d'amministratô possan modificala da-o momento ch'a l'é inclusa seleçionando a proteçion \"ricorsciva\" {{PLURAL:$1|inta paggina|inte paggine}}:",
        "permissionserrors": "No ti g'hæ o permisso",
        "permissionserrorstext": "No ti g'hæ i permissi pe fâlo, pe  {{PLURAL:$1|questa raxon|queste raxoin}}:",
        "permissionserrorstext-withaction": "No ti g'hæ i permìssi pe $2 pe {{PLURAL:$1|sta raxon|ste raxoìn}}:",
-       "contentmodelediterror": "No ti peu modificâ sta verscion da-o momento che o so modello de contegnuo o l'è <code>$1</code>, mentre o corrente modello de contegnuo da paggina o l'è <code>$2</code>.",
+       "contentmodelediterror": "No ti peu modificâ sta verscion da-o momento che o so modello de contegnuo o l'è <code>$1</code>, ch'o diffeisce da-o corrente modello de contegnuo da paggina <code>$2</code>.",
        "recreate-moveddeleted-warn": "Atençión: ti stæ pe ricreâ 'na pàgina zà scancelâ into passòu.'''\n\nConsciddera se l'è o caxo de continoâ  a cangiâ 'sta pàgina.\nPe comoditæ e cancellaçioìn e i stramui son pubricæ chì sotta:",
        "moveddeleted-notice": "Sta pàgina a l'é stæta scancelâ.\nA lista de scancelaçioìn e di stramui son riportæ chi de sotta pe informaçión.",
        "moveddeleted-notice-recent": "Spiaxenti, sta paggina a l'è stæta scassâ reçentemente (inte urtime 24 oe).\n\nE açioin de cançellaçion e spostamento pe questa paggina son disponibile chì appreuvo pe referença.",
        "content-model-javascript": "JavaScript",
        "content-json-empty-object": "Ogetto veuo",
        "content-json-empty-array": "Array veuo",
+       "deprecated-self-close-category": "Paggine ch'adoeuvian di tag HTML aoto-ciosi non vallidi",
+       "deprecated-self-close-category-desc": "A pagina a conten di tag HTML aoto-ciosi non vallidi, comme <code>&lt;b/></code> o <code>&lt;span/></code>. O comportamento de questi fito o cangiâ pe ese coerente co-e specifiche HTML5, pe questo o so utilizzo into wikitesto o l'è deprecou.",
        "duplicate-args-warning": "<strong>Avvertensa:</strong> [[:$1]] o ciamma [[:$2]] con ciù de un valô pe-o parammetro \"$3\".  Solo l'urtimo valô fornio o saiâ deuviou.",
        "duplicate-args-category": "Paggine che ciamman i template deuviando di parammetri duplicæ",
        "duplicate-args-category-desc": "A paggina a conten de ciamæ a di template ch'adeuvian di argomenti duplicæ, comme presempio <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ò <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "rev-deleted-no-diff": "No ti peu amiâ sto diff percose un-a de verscioin a l'è stæta '''scassâ'''.\nConsurta a [{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} lista de cançellaçioin] pe-i dettaggi.",
        "rev-suppressed-no-diff": "No ti peu fâ sto confronto tra verscioin perché un-a a l'è stæta '''scassâ'''.",
        "rev-deleted-unhide-diff": "Un-a de verscioin de sto confronto a l'è stæta '''scassâ'''.\nConsurta a [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} lista de cançellaçioin] pe-i dettaggi.\nTi ti peu ancon [$1 fâ sto confronto] se necessaio.",
+       "rev-suppressed-unhide-diff": "Un-a de verscioin de sto confronto a l'è stæta '''sopressa'''.\nConsurta a [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} lista de cançellaçioin] pe-i dettaggi.\nTi peu ancon [$1 fâ sto confronto] se necessaio.",
+       "rev-deleted-diff-view": "Un-a de verscioin de sto confronto a l'è stæta '''scassâ'''.\nTi ti peu amiala; consurta o [{{fullurl:{{#Special:Log}}/suppress|page={{PAGENAMEE}}}} recistro de rimoçioin] pe-i dettaggi.",
+       "rev-suppressed-diff-view": "Un-a de verscioin de sto confronto a l'è stæta '''sopressa'''.\nTi ti peu amiâla; consurta o [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registro de soprescioin] pe-i dettaggi.",
        "rev-delundel": "fanni védde/ascondi",
        "rev-showdeleted": "mostra",
        "revisiondelete": "Scassa ò ripristina verscioin",
        "revdelete-nooldid-title": "Verscion non specificâ",
+       "revdelete-nooldid-text": "No t'hæ speçificou nisciun-a revixon in sciâ quæ eseguî questa fonçion, oppû a revixon speçificâ a no l'existe, ò che donque t'ê aproeuvo a çercâ d'asconde a revixon attuale.",
        "revdelete-no-file": "O file specificou o no l'existe.",
        "revdelete-show-file-confirm": "T'ê seguo de voei amiâ a verscion scassâ do file \"<nowiki>$1</nowiki>\" do $2 a $3?",
        "revdelete-show-file-submit": "Sci",
        "revdelete-selected-text": "{{PLURAL:$1|Verscion seleçionâ|Verscioin seleçionæ}} de [[:$2]]:",
        "revdelete-selected-file": "{{PLURAL:$1|Verscion seleçionata|Verscioin seleçionæ}} do file [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|Evento do registro seleçionou|Eventi do registro seleçionou}}:",
+       "revdelete-text-text": "E verscioin scassæ apparian ancon inta cronologia da pagina, ma parte do so contegnuo o saiâ inaccescibile a-o pubbrico.",
+       "revdelete-text-file": "E verscioin di file scassæ apparian ancon inta cronologia do file, ma parte do so contegnuo a saiâ inaccescibile a-o pubbrico.",
+       "logdelete-text": "I eventi scassæ apparian ancon inti registri, ma 'na parte do so contegnuo a saiâ inaccescibile a-o pubbrico.",
+       "revdelete-text-others": "Di atri amministratoî saian ancon in grou de accede a-i contegnui ascoxi e porian ripristinali, se no l'è stæto impostou de restriçioin azontive.",
+       "revdelete-confirm": "Pe piaxei conferma che questo l'è quante t'intendi fâ, che t'accapisci e conseguençe, e che ti o fæ into rispetto de [[{{MediaWiki:Policy-url}}|linnie guidda]].",
+       "revdelete-suppress-text": "A rimoçion a saiæ da doeuviâ '''solo''' che inti seguenti caxi:\n* informaçioin potençialmente diffamatoie\n* dæti personæ inoportun\n*: ''indiriççi, nummeri de teleffono, coddiçi fiscali, ecc.''",
        "revdelete-legend": "Imposta e limitaçioin de vixibilitæ:",
        "revdelete-hide-text": "Testo da verscion",
        "revdelete-hide-image": "Ascondi i contegnui do file",
        "revdelete-unsuppress": "Elimmina e limitaçioin in scê verscioin ripristinæ",
        "revdelete-log": "Raxon:",
        "revdelete-submit": "Applica {{PLURAL:$1|a-a verscion seleçionâ|a-e verscioin seleçionæ}}",
-       "revdelete-success": "'''Vixibilitæ da verscion agiornâ con successo.'''",
+       "revdelete-success": "'''Vixibilitæ da verscion agiornâ.'''",
        "revdelete-failure": "'''A vixibilitæ da verscion a no peu ese agiornâ:'''\n$1",
-       "logdelete-success": "'''Registro de vixibilitæ impostou con successo.'''",
+       "logdelete-success": "'''Registro de vixibilitæ impostou.'''",
        "logdelete-failure": "No s'è posciuo impostâ o registro de vixibilitæ: $1",
        "revdel-restore": "càngia a vixibilitæ",
        "pagehist": "Stoia da paggina",
        "revdelete-modify-no-access": "Imposcibbile modificâ l'ogetto con dæta $1 $2 in quanto o l'è stæto identificou comme \"riservou\" e no se dispon-e do relativo accesso.",
        "revdelete-modify-missing": "Imposcibbile modificâ l'ogetto con ID $1: into database o no gh'è!",
        "revdelete-no-change": "'''Attençion:''' l'ogetto con dæta $1 $2 o l'aveiva zà e impostaçioin de vixibilitæ domandæ.",
+       "revdelete-concurrent-change": "Imposcibile modificâ l'ogetto con dæta $1, $2: pâ che o so stato o segge stæto modificou da un atro utente dementre che ti ti çercavi de modificalo.",
+       "revdelete-only-restricted": "Errô inte l'asconde l'ogetto datou $1, $2: no ti poeu asconde i ogetti a-i amministratoî sença seleçionâ un-a di atre opçioin de vixibilitæ.",
        "revdelete-reason-dropdown": "* Raxoin ciù comun-e pe-o scassamento\n** Violaçion do drito d'outô\n** Commenti ò informaçioin personæ inappropiæ\n** Nomme utente inappropiou\n** Informaçion potençialmente diffamatoia",
        "revdelete-otherreason": "Un atro motivo:",
        "revdelete-reasonotherlist": "Un'atra raxon",
        "revdelete-edit-reasonlist": "Modiffica e raxoin do scassamento",
        "revdelete-offender": "Aotô da verscion:",
        "suppressionlog": "Registro de sopprescioin",
+       "suppressionlogtext": "De sotta gh'è 'na lista de scassatue e di brocchi con do contegnuo ascoso a-i amministratoî.\nAmia a [[Special:BlockList|lista di blocchi]] pe l'elenco di bandi e di blocchi attivi a-o momento.",
        "mergehistory": "Union de stoie da paggina",
+       "mergehistory-header": "Questa pagina a consente de unî e verscioin d'a cronologia de 'na pagina sorgente a 'na pagina ciù reçente.\nAsseguite che sto cangio o mantegne a continuitæ storica da pagina.",
        "mergehistory-box": "Unisci a stoia de doe paggine:",
        "mergehistory-from": "Paggina d'origgine:",
        "mergehistory-into": "Paggina de destinaçion:",
        "mergehistory-empty": "Nisciun-a verscion da unî.",
        "mergehistory-done": "{{PLURAL:$3|Una verscion de $1 a l'è stæta unia|$3 vercsioin de $1 son stæte unie}} a-a stoia de [[:$2]].",
        "mergehistory-fail": "Imposcibbile unî e stoie. Verificâ a paggina e i parammetri temporali.",
+       "mergehistory-fail-bad-timestamp": "O timestamp o no l'è vallido.",
+       "mergehistory-fail-invalid-source": "A pagina sorgente a no l'è vallida.",
+       "mergehistory-fail-invalid-dest": "A pagina de destinaçion a no l'è vallida.",
+       "mergehistory-fail-no-change": "L'union de cronologie a no l'ha unio arcun-a verscion. Ricontrolla e pagine e i parametri temporali.",
+       "mergehistory-fail-permission": "Aotorizzaçioin insuffixente pe unî e cronologie.",
+       "mergehistory-fail-self-merge": "A paggina d'origgine e quella de destinaçion son a mæxima",
+       "mergehistory-fail-timestamps-overlap": "E verscioin d'origine se sorvepon-an ò vegnan doppo e verscioin de destinaçion.",
        "mergehistory-fail-toobig": "Imposcibbile eseguî l'union da stoia essendoghe ciu che o limmite de $1 {{PLURAL:$1|verscion|verscioin}} da mesciâ.",
        "mergehistory-no-source": "A paggina d'origgine $1 a no l'existe.",
        "mergehistory-no-destination": "A paggina de destinaçion $1 a no l'existe.",
        "diff-multi-sameuser": "({{PLURAL:$1|Una verscion intermedia|$1 De verscioin intermedie}} de 'n mæximo utente {{PLURAL:$1|a no l'è mostrâ|no son mostræ}})",
        "diff-multi-otherusers": "({{PLURAL:$1|Una verscion intermedia|$1 De verscioin intermedie}} de {{PLURAL:$2|'n atro utente|$2 utenti}} {{PLURAL:$1|a no l'è mostrâ|no son mostræ}})",
        "diff-multi-manyusers": "({{PLURAL:$1|Una verscion intermedia|$1 verscioin intermedie}} de ciu che $2 {{PLURAL:$2|utente|utenti}} non {{PLURAL:$1|mostrâ|mostræ}})",
+       "difference-missing-revision": "{{PLURAL:$2|Una verscion|$2 verscioin}} de questa differença ($1) {{PLURAL:$2|a no l'è stæta atrovâ|no son stæte atrovæ}}.\n\nQuesto succede a l'uso se inta stoia ti sciacchi un vegio ingancio a una paggina scassâ.\n\nI dettaggi ti-i peu attrovâ into [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de scançellaçioin].",
        "searchresults": "Resultati da reçerca",
        "searchresults-title": "Rezoltati da riçerca de \"$1\"",
        "titlematches": "Corispondençe into tittolo de paggine",
        "powersearch-togglenone": "Nisciun",
        "powersearch-remember": "Aregordite a seleçion pe-e proscime riçerche",
        "search-external": "Riçerca esterna",
-       "searchdisabled": "La riçerca de {{SITENAME}} a no l'è attiva. Into fra tempo ti peu çercâ in sce Google. \nNotta che i seu indexi di contegnui de {{SITENAME}} porrieivan no ese aggiornæ.)",
+       "searchdisabled": "A riçerca de {{SITENAME}} a no l'è attiva. Into fratempo ti peu çercâ in sce Google. \nNotta che i so indexi di contegnui de {{SITENAME}} porrieivan no ese aggiornæ.",
        "search-error": "S'è verificou 'n errô durante a riçerca: $1",
        "preferences": "Preferençe",
        "mypreferences": "Preferençe",
        "recentchangesdays-max": "Mascimo $1 {{PLURAL:$1|giorno|giorni}}",
        "recentchangescount": "Nummero de modiffiche da mostrâ pe difetto:",
        "prefs-help-recentchangescount": "Comprende i urtime modiffiche, paggine de stoie e registri.",
+       "prefs-help-watchlist-token2": "Questa a l'è a ciave segretta pe-o feed web di to oservæ.\nChiunque a conosce saiâ in graddo de leze i to oservæ, quindi no stanni a condividdila. [[Special:ResetTokens|Clicca chi se ti g'hæ de besoeugno de rempostâla]].",
        "savedprefs": "E teu preferençe son stæte sarvæ.",
        "savedrights": "I driti utente de {{GENDER:$1|$1}} son stæti sarvæ.",
        "timezonelegend": "Fuso oraio:",
        "prefs-custom-css": "CSS personalizzou",
        "prefs-custom-js": "JavaScript personalizzou",
        "prefs-common-css-js": "CSS/JavaScript condiviso pe tutte e pelle:",
+       "prefs-reset-intro": "L'è poscibile doeuviâ sta pagina pe rimpostâ e propie preferençe a quelle predefinie do scito.\nL'opiaçion a no poeu ese annullâ.",
        "prefs-emailconfirm-label": "Conferma de l'e-mail:",
        "youremail": "Indirìsso email:",
        "username": "{{GENDER:$1|Nomme utente}}:",
        "yourvariant": "Variante da lengoa do contegnuo:",
        "prefs-help-variant": "A variante o grafia co-a quæ ti prefeisci che e paggine do wiki seggian mostræ.",
        "yournick": "Nomiagio:",
+       "prefs-help-signature": "I commenti inte pagine de discuscion devan ese firmæ con \"<nowiki>~~~~</nowiki>\" ch'o saiâ convertio inta proppia firma seguia da-a dæta.",
        "badsig": "Errô in ta firma; controlla i comandi HTML.",
        "badsiglength": "A firma scelta a l'è troppo longa.\nA non deve passâ $1 {{PLURAL:$1|carattere|caratteri}}.",
+       "yourgender": "Comme rifeise a ti?",
+       "gender-unknown": "Into mençunâte, o software o l'adoeuviâ de paole de genere noeütro ogni votta che saiâ poscibile",
        "gender-male": "O l'è registrou insce {{SITENAME}}",
        "gender-female": "A l'è registrâ insce {{SITENAME}}",
        "prefs-help-gender": "L'impostassion de sta preferensa a l'è opsionâ.\nO software o deuvia sto valô pe addressâse a ti e mensunate a-i atri deuviando o gennere grammaticale apropiou.\nQuesta informassion a saiâ pubblica.",
        "userrights": "Manezzo di driti di utenti",
        "userrights-lookup-user": "Gestisci i gruppi di utenti",
        "userrights-user-editname": "Scrivi o teu nomme utente:",
-       "editusergroup": "Modiffica i gruppi di utenti",
+       "editusergroup": "Modiffica groppi {{GENDER:$1|utente}}",
        "editinguser": "Apreuvo a cangiâ i driti de l'{{GENDER:$1|utente}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Modiffica i gruppi di utenti",
-       "saveusergroups": "Sarva i gruppi di utenti",
+       "saveusergroups": "Sarva groppi {{GENDER:$1|utente}}",
        "userrights-groupsmember": "Membro de:",
        "userrights-groupsmember-auto": "Membro impliçito de:",
+       "userrights-groups-help": "L'è poscibile modificâ i groppi de st'utente:\n* Una casella marcâ voeu dî che l'utente o l'è inte quello groppo.\n* Una casella smarcâ voeu dî che l'utente o no l'è inte quello groppo.\n* O scimbolo * o voeu dî che no ti poeu smarcâ o groppo una votta che ti l'hæ azonto (ò viçeversa).",
        "userrights-reason": "Raxon:",
        "userrights-no-interwiki": "No ti g'hæ i permissi pe modificâ i driti di utenti insce di atre wiki.",
        "userrights-nodatabase": "O database $1 o no l'esiste ò o no l'è un database locale.",
        "userrights-changeable-col": "Gruppi che ti peu modificâ",
        "userrights-unchangeable-col": "Gruppi che no ti peu modificâ",
        "userrights-conflict": "Conflito de modiffica di driti utente! Pe piaxei controlla e conferma e teu modiffiche.",
-       "userrights-removed-self": "T'hæ rimosso con successo i teu driti. E quindi, no ti saiæ ciù in grou de accede a questa paggina.",
+       "userrights-removed-self": "T'hæ rimosso i teu driti. E quindi, no ti saiæ ciù in grou de accede a questa paggina.",
        "group": "Gruppo:",
        "group-user": "Ûtenti",
        "group-autoconfirmed": "Utenti aotoconfermæ",
        "grouppage-sysop": "{{ns:project}}:Amministratoî",
        "grouppage-bureaucrat": "{{ns:project}}:Buroccrati",
        "grouppage-suppress": "{{ns:project}}:Soppressoî",
+       "right-read": "Leze paggine",
+       "right-edit": "Modiffica paggine",
+       "right-createpage": "Crea paggine (escluse e pagine de discuscion)",
+       "right-createtalk": "Crea pagine de discuscion",
+       "right-createaccount": "Crea noeuve utençe",
+       "right-autocreateaccount": "Accede aotomaticamente con un'utença esterna",
+       "right-minoredit": "Marca e modifiche comme menoî",
        "right-move": "Mescia e paggine",
+       "right-move-subpages": "Mescia e pagine insemme a-e relative sottopagine",
+       "right-move-rootuserpages": "Mescia e pagine prinçipæ di utenti",
+       "right-move-categorypages": "Mescia e categorie",
+       "right-movefile": "Mescia i file",
+       "right-suppressredirect": "O no crea un redirect aotomatico quande se mescia una pagina",
+       "right-upload": "Carrega file",
+       "right-reupload": "Sorvescrive un file existente",
+       "right-reupload-own": "Sorvescrive un file existente caregou da-o mæximo utente",
+       "right-reupload-shared": "Sorvescrive localmente di file presenti inte l'archivio condiviso",
+       "right-upload_by_url": "Carega un file da un addreçço URL",
+       "right-purge": "Nettezza a cache do scito sença conferma",
+       "right-autoconfirmed": "Non soggetto a-o limmite de açioin pe IP",
+       "right-bot": "Da trattâ comme processo aotomatico",
+       "right-nominornewtalk": "Fa scì che e modiffiche menoî a-e pagine de discuscion no faççan comparî l'avviso de noeuvo messaggio",
+       "right-apihighlimits": "Doeuvia di limmiti ciù erti pe-e interrogaçioin API",
        "right-writeapi": "Deuvia l'API in scrittua",
+       "right-delete": "Scassa e paggine",
+       "right-bigdelete": "Scassa e pagine con cronologie longhe",
+       "right-deletelogentry": "Scassa e ripristina voxe de registro specifiche",
+       "right-deleterevision": "Scassa e ripristina de verscion specifiche de pagine",
+       "right-deletedhistory": "Vixualizza e verscioin da cronologia scassæ, sença o so testo associou",
+       "right-deletedtext": "Vixualizza o testo scassou e-e modifiche fra de verscioin scassæ",
+       "right-browsearchive": "Çerca inte pagine scassæ",
+       "right-undelete": "Recuppera una paggina",
+       "right-suppressrevision": "Vedde, asconde e ripristina de verscioin specifiche de pagine a quæ-se-segge utente",
+       "right-viewsuppressed": "Vedde de verscioin ascose a qua-se-sæ utente",
+       "right-suppressionlog": "Vixualizza i registri privæ",
+       "right-block": "Blocca e modifiche di atri utenti",
+       "right-blockemail": "Impedisce a un utente de mandâ de email",
+       "right-hideuser": "Blocca un nomme utente, ascondendolo a-o pubbrico",
+       "right-ipblock-exempt": "Ignora i blocchi di IP, i blocchi aotomatichi e i blocchi de range de IP",
+       "right-unblockself": "Sblocca lê mæximo",
+       "right-protect": "Camgia i livelli de proteçion e modifica e pagine protette ricorscivamente",
+       "right-editprotected": "Modifica e pagine protette con \"{{int:protect-level-sysop}}\"",
+       "right-editsemiprotected": "Modifica e pagine protette con \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editcontentmodel": "Modifica o modello de contegnuo de 'na paggina",
+       "right-editinterface": "Modiffica l'interfaccia utente",
+       "right-editusercssjs": "Modifica i file CSS e JS di atri utenti",
+       "right-editusercss": "Modifica i file CSS di atri utenti",
+       "right-edituserjs": "Modiffica i file JS di atri utenti",
+       "right-editmyusercss": "Modifica o file CSS do proppio utente",
+       "right-editmyuserjs": "Modifica o file JavaScript do proppio utente",
+       "right-viewmywatchlist": "Vixualizza i proppi osservæ speçiali",
+       "right-editmywatchlist": "Modifica i to osservæ speçiali. Da notâ che arcun-e açioin porian ancon azonze de pagine anche sença questo drito.",
+       "right-viewmyprivateinfo": "Vixualizza i proppi dæti personæ (presempio: adreçço email, nomme veo)",
+       "right-editmyprivateinfo": "Modiffica i proppi dæti personæ (presempio: addreçço email, nomme veo)",
+       "right-editmyoptions": "Modiffica e proppie preferençe",
+       "right-rollback": "Annulla rapidamente e modifiche de l'urtimo utente ch'o l'ha modificou una pagina in particolâ",
+       "right-markbotedits": "Marca e modifiche soggette a rollback comme effettuæ da bot",
+       "right-noratelimit": "No soggetto a-o limmite de açioin",
+       "right-import": "Importa de pagine da di atri wiki",
+       "right-importupload": "Importa paggine da un upload de file",
+       "right-patrol": "Marca e modifiche di altri utenti comme controllæ",
+       "right-autopatrol": "Marca aotomaticamente e proppie modifiche comme controllæ",
+       "right-patrolmarks": "Doeuvia a fonçion de verifica di urtime modiffiche",
+       "right-unwatchedpages": "Vixualizza una lista de pagine non öservæ",
+       "right-mergehistory": "Unisce a cronologia de paggine",
+       "right-userrights": "Modiffica tutti i driti de l'utente",
+       "right-userrights-interwiki": "Modiffica i driti di utenti insce di atre wiki",
+       "right-siteadmin": "Abbrocca e sbrocca o database",
+       "right-override-export-depth": "Esporta e paggine includendo e pagine collegæ scin a 'na profonditæ de 5",
+       "right-sendemail": "Manda de email a di atri utenti",
+       "right-passwordreset": "Vedde i messaggi de rempostaçion da password",
+       "right-managechangetags": "Crea e attiva/disattiva i [[Special:Tags|etichette]]",
+       "right-applychangetags": "Apprica di [[Special:Tags|etichette]] a-e proppie modiffiche",
+       "right-changetags": "Azonze e leva de specifiche [[Special:Tags|etichette]] insce scingole verscioin o voxe de registro",
+       "right-deletechangetags": "Scassa i [[Special:Tags|etichette]] da-o database",
+       "grant-generic": "Pacchetto diritti \"$1\"",
+       "grant-group-page-interaction": "Interagisce co-e paggine",
+       "grant-group-file-interaction": "Interagisce co-i file murtimediali",
+       "grant-group-watchlist-interaction": "Interagisce con i to oservæ speçiali",
+       "grant-group-email": "Invia email",
+       "grant-group-high-volume": "Esegue açioin mascive",
+       "grant-group-customization": "Personalizzaçion e preferençe",
+       "grant-group-administration": "Esegue açioin amministrative",
+       "grant-group-other": "Attivitæ varrie",
+       "grant-blockusers": "Blocca e sblocca utenti",
+       "grant-createaccount": "Crea un'utença",
+       "grant-createeditmovepage": "Crea, modiffica e mescia e pagine",
+       "grant-delete": "Scassa pagine, revixoin, e voxe de registro",
+       "grant-editinterface": "Modifica o namespace MediaWiki e i CSS/JavaScript di utenti",
+       "grant-editmycssjs": "Modifica i CSS/JavaScript da to utença",
+       "grant-editmyoptions": "Modifica e preferençe da to utença",
+       "grant-editmywatchlist": "Modiffica a to lista di öservæ",
+       "grant-editpage": "Modifica pagine existente",
+       "grant-editprotected": "Modifica pagine protette",
+       "grant-highvolume": "Modiffiche mascive",
+       "grant-oversight": "Asconde i utenti e soprimme e revixoin",
+       "grant-patrol": "Marca e modifiche a-e paggine comme veificæ",
+       "grant-protect": "Proteze e sproteze e paggine",
+       "grant-rollback": "Rollback de modifiche a-e pagine",
+       "grant-sendemail": "Manda di email a di atri utenti",
+       "grant-uploadeditmovefile": "Carega, sostituisce e mescia i file",
+       "grant-uploadfile": "Carrega di noeuvi file",
+       "grant-basic": "Driti de base",
+       "grant-viewdeleted": "Vedde i file e e pagine scassæ",
+       "grant-viewmywatchlist": "Vedde i to öservæ speçiali",
        "newuserlogpage": "Nêuvi utenti",
+       "newuserlogpagetext": "Questo o l'è un registro de creaçioin di utençe.",
        "rightslog": "Diritti d'ûtente",
+       "rightslogtext": "Questo o l'è un registro di cangi a-i driti di utenti.",
+       "action-read": "leze sta paggina",
        "action-edit": "càngia sta pàgina",
+       "action-createpage": "creâ sta paggina",
+       "action-createtalk": "creâ sta paggina de discuscion",
+       "action-createaccount": "creâ st'utença",
+       "action-autocreateaccount": "creâ aotomaticamente st'utença esterna",
+       "action-history": "vedde a cronologia de sta pagina",
+       "action-minoredit": "marcâ sta modifica comme menô",
+       "action-move": "mesciâ sta pagina",
+       "action-move-subpages": "mesciâ sta pagina e e relative sottopagine",
+       "action-move-rootuserpages": "mesciâ e paggine prinçipæ di utenti",
+       "action-move-categorypages": "mesciâ e categorie",
+       "action-movefile": "mesciâ sto file",
+       "action-upload": "caregâ sto file",
+       "action-reupload": "sorvescrive sto file existente",
+       "action-reupload-shared": "soviascrive sto file presente inte l'archivio condiviso",
+       "action-upload_by_url": "caregâ sto file da un addreçço URL",
+       "action-writeapi": "deuviâ l'API in scrittua",
+       "action-delete": "scassâ 'sta paggina",
+       "action-deleterevision": "scassâ sta verscion",
+       "action-deletedhistory": "vixualizzâ a cronologia scassâ de sta pagina",
+       "action-browsearchive": "çercâ paggine scassæ",
        "action-undelete": "Recuppera sta paggina",
        "action-suppressrevision": "rivedde e ripristinâ e modiffiche ascose",
+       "action-suppressionlog": "vedde questo registro privou",
+       "action-block": "bloccâ st'utente in scrittua",
+       "action-protect": "modificâ i livelli de proteçion pe questa pagina",
+       "action-rollback": "annullâ rapidamente e modifiche de l'urtimo utente ch'o l'ha modificou una pagina determinâ",
+       "action-import": "importâ de pagine da 'n'atra wiki",
+       "action-importupload": "importâ de pagine tramite upload da file",
+       "action-patrol": "marcâ e modifiche di atri utenti comme controllæ",
+       "action-autopatrol": "marcâ e proppie modifiche comme controllæ",
+       "action-unwatchedpages": "vixonâ a lista de pagine non öservæ",
+       "action-mergehistory": "unî a cronologia de sta pagina",
+       "action-userrights": "modificâ tutti i driti di utenti",
+       "action-userrights-interwiki": "modificâ i driti di utenti insce di atre wiki",
+       "action-siteadmin": "broccâ e sbroccâ o database",
+       "action-sendemail": "mandâ di e-mail",
+       "action-editmywatchlist": "modificâ a to lista di öservæ",
+       "action-viewmywatchlist": "vedde i to öservæ speçiali",
+       "action-viewmyprivateinfo": "vedde i proppi dæti personali",
+       "action-editmyprivateinfo": "modificâ i proppi dæti personali",
+       "action-editcontentmodel": "modificâ o modello de contegnuo de 'na paggina",
+       "action-managechangetags": "creâ e attivâ/disattivâ i etichette",
+       "action-applychangetags": "appricâ di etichette a-e to modiffiche",
+       "action-changetags": "Azonze e levâ de specifiche etichette sciu scingole verscioin o voxe de registro",
+       "action-deletechangetags": "scassâ i etichette da-o database",
        "nchanges": "$1 {{PLURAL:$1|modiffica|modiffiche}}",
+       "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|da l'urtima vixita}}",
        "enhancedrc-history": "cronologia",
        "recentchanges": "Ùrtimi cangiamenti",
        "recentchanges-legend": "Opçioin di ùrtimi cangiaménti",
        "recentchanges-summary": "Questa pàgina a g'ha di càngi ciù reçenti a-i contegnûi do scîto.",
+       "recentchanges-noresult": "Nisciun-a modiffica durante o periodo inseio ch'a soddisfe sti critei.",
        "recentchanges-feed-description": "Questo feed o g'ha di cangiaménti ciù reçenti a-i contegnûi do scîto.",
        "recentchanges-label-newpage": "Sto cangiaménto o l'à creòu 'na pàgina nêuva",
        "recentchanges-label-minor": "Cangiamento minô (m)",
        "recentchanges-label-plusminus": "Variassion da paggina in nummero de byte",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (veddi e [[Special:NewPages|neuve paggine]])",
-       "rcnotefrom": "Chì sotta gh'è i cangiamenti fæti comensando da '''$2''' (scin a '''$1''').",
+       "recentchanges-submit": "Fanni vedde",
+       "rcnotefrom": "Chì sotta gh'è {{PLURAL:$5|o cangiamento|i cangiamenti}} a partî da <strong>$3, $4</strong> (scin a '''$1''').",
        "rclistfrom": "Fanni vedde e modiffiche apportæ partindo da $3 $2",
        "rcshowhideminor": "$1 cangiaménti minoi",
        "rcshowhideminor-show": "Fanni vedde",
        "rcshowhidebots-show": "Fanni vedde",
        "rcshowhidebots-hide": "Ascondi",
        "rcshowhideliu": "$1 i utenti registræ",
+       "rcshowhideliu-show": "Fanni vedde",
        "rcshowhideliu-hide": "Ascondi",
        "rcshowhideanons": "$1 utenti anonnimi",
        "rcshowhideanons-show": "Fanni vedde",
        "rcshowhideanons-hide": "Ascondi",
        "rcshowhidepatr": "$1 i cangiaménti controllæ",
+       "rcshowhidepatr-show": "Fanni vedde",
+       "rcshowhidepatr-hide": "Ascondi",
        "rcshowhidemine": "$1 i mæ cangiamenti",
        "rcshowhidemine-show": "Fanni vedde",
        "rcshowhidemine-hide": "Ascondi",
+       "rcshowhidecategorization": "$1 categorizzaçion da pagina",
+       "rcshowhidecategorization-show": "Fanni vedde",
+       "rcshowhidecategorization-hide": "Ascondi",
        "rclinks": "Fanni vedde i $1 cangiaménti ciù reçenti fæti inti ùrtimi $2 giorni<br />$3",
        "diff": "diff",
        "hist": "stö",
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
+       "number_of_watching_users_pageview": "[osservâ da {{PLURAL:$1|un utente|$1 utenti}}]",
+       "rc_categories": "Limite a-e categorie (separæ da \"|\"):",
        "rc_categories_any": "Quâ-se-sæ fra quelle indicæ",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} doppo a modiffica",
        "newsectionsummary": "/* $1 */ neuva seçion",
        "recentchangeslinked-page": "Nómme da pàgina:",
        "recentchangeslinked-to": "Fanni védde sôlo i cangiaménti a-e pàgine colegæ a-a pàgina specificâ",
        "recentchanges-page-added-to-category": "[[:$1]] azonto a-a categoria",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] e [[Special:WhatLinksHere/$1|{{PLURAL:$2|una paggina a l'è azonta|$2 paggine son azonte}}]] a-a categoria",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] azonta a-a categoria, [[Special:WhatLinksHere/$1|questa pagina a l'è inclusa a l'interno di atre pagine]]",
        "recentchanges-page-removed-from-category": "[[:$1]] rimosso da-a categoria",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] e {{PLURAL:$2|una paggina a l'è rimossa|$2 paggine son rimosse}} da-a categoria",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] rimossa da-a categoria, [[Special:WhatLinksHere/$1|questa pagina a l'è inclusa a l'interno di atre pagine]]",
        "autochange-username": "Modiffica aotomattica MediaWiki",
        "upload": "Carrega 'n file",
        "uploadbtn": "Carrega 'n file",
        "reuploaddesc": "Torna a-o moddulo pe-o caregamento.",
        "upload-tryagain": "Invia a descrission do file modificou",
        "uploadnologin": "No t'ê introu",
+       "uploadnologintext": "Pe caregaâ  di file bezoeugna $1.",
+       "upload_directory_missing": "A directory de upload ($1) a no l'existe e a no poeu ese creâ da-o server web.",
+       "upload_directory_read_only": "O server web o no l'è in graddo de scrive inta directory de upload ($1).",
+       "uploaderror": "Errô into caregamento",
+       "upload-recreate-warning": "<strong>Attençion: un file con questo nomme o l'è stæto scassou o mesciou.</strong>\nO registro de scassatue e di stramui de questa pagina o l'è riportou chì pe comoditæ:",
+       "uploadtext": "Doeuviâ o modulo sottostante pe caregâ di noeuvi file. Pe visualizzâ ò çercâ i file za caregæ, consultâ o [[Special:FileList|log di file caregæ]]. Caregamenti de file e de noeuve verscioin de file son registræ into [[Special:Log/upload|log di upload]], e scassatue into [[Special:Log/delete|log de scassatue]].\n\nPe insei un file a l'interno de 'na pagina, fanni un collegamento de questo tipo:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' pe doeuviâ a verscion completa do file\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|testo alternativo]]</nowiki></code>''' pe doeuviâ una verscion larga 200 pixel inseia inte 'n box, alliniâ a scinistra e con 'testo alternativo' comme didascalia\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' pe generâ un collegamento diretto a-o file sença vixualizzâlo",
+       "upload-permitted": "{{PLURAL:$2|Tipo de file consentio|Tipi de file consentii}}: $1.",
+       "upload-preferred": "{{PLURAL:$2|Tipo de file consegiou|Tipi de file consegiæ}}: $1.",
+       "upload-prohibited": "{{PLURAL:$2|Tipo de file non consentio|Tipi de file non consentii}}: $1.",
        "uploadlogpage": "Log di file caregæ",
+       "uploadlogpagetext": "De sotta gh'è una lista di urtimi file caregæ.\nConsultâ a [[Special:NewFiles|galleria di noeuvi file]] pe 'na vixon d'insemme.",
        "filename": "Nomme do file",
        "filedesc": "Detaggi",
+       "fileuploadsummary": "Detaggi do file:",
+       "filereuploadsummary": "Cangiamenti a-o file:",
+       "filestatus": "Informaçioin in sciô copyright:",
        "filesource": "Reixe:",
+       "ignorewarning": "Ignora l'avviso e sarva comunque o file",
+       "ignorewarnings": "Ignora i messaggi de avvertimento do scistema",
+       "minlength1": "O nome do file o dev'ese a-o manco de una lettia.",
+       "illegalfilename": "O nomme \"$1\" o conten di caratteri non ammissi inti tittoli de paggine. Dagghe 'n atro nomme e proeuva torna a caregâlo.",
+       "filename-toolong": "I nommi di file no poeuan superâ i 240 byte.",
        "badfilename": "O nomme do file o l'è stæto cangiòu in \"$1\".",
-       "fileexists": "Un papê co sto nomme o existe de zà, pe piaxei da unn'euggiâ a <strong>[[:$1]]</strong> se non ti tei seguo de voleilo cangiâ.\n[[$1|thumb]]",
-       "fileexists-forbidden": "Un papê co sto nomme o existe de zà, pe piaxei vanni in derrê e carega sto papê co un ätro nomme. [[File:$1|thumb|center|$1]]",
+       "filetype-mime-mismatch": "L'estenscion do file \".$1\" a no corrisponde a-o tipo MIME rilevou da-o file ($2).",
+       "filetype-badmime": "No l'è consentio de caregâ di file de tipo MIME \"$1\".",
+       "filetype-bad-ie-mime": "Imposcibile caregâ o file perché Internet Explorer o rilevieiva comme \"$1\", ch'o l'è un tipo de file non consentio e potençialmente peigoso.",
+       "filetype-unwanted-type": "Caregâ di file de tipo '''\".$1\"''' l'è sconsegiou. {{PLURAL:$3|O tipo de file consegiou o l'è|I tipi de file consegiæ son}} $2.",
+       "filetype-banned-type": "'''\".$1\"''' {{PLURAL:$4|o no l'è un tipo de file consentio|no son di tipi de file consentii}}. {{PLURAL:$3|O tipo de file consentio o l'è|I tipi de file consentii son}} $2.",
+       "filetype-missing": "O file o no g'ha d'estenscion (pres. \".jpg\").",
+       "empty-file": "O file che t'hæ inviou o l'è voeuo.",
+       "file-too-large": "O file che t'hæ inviou o l'è troppo grande.",
+       "filename-tooshort": "O nomme do file o l'è troppo curto.",
+       "filetype-banned": "Questo tipo de file o l'è proibio.",
+       "verification-error": "Questo file o no l'ha superou a veriffica.",
+       "hookaborted": "A modiffica che t'hæ çercou de fâ a l'è stæta interrotta da un'estenscion.",
+       "illegal-filename": "O nomme do file o no l'è ammisso.",
+       "overwrite": "Soviascrive un file existente no l'è permisso.",
+       "unknown-error": "Gh'è stæto un aro sconosciuo.",
+       "tmp-create-error": "Imposcibbile creâ o file temporannio.",
+       "tmp-write-error": "Errô de scrittua do file temporannio.",
+       "large-file": "Se raccomanda de no superâ e dimenscioin de $1 pe ciascun file; questo file o l'è grande $2.",
+       "largefileserver": "O file o suppera e dimenscioin consentie da-a configuaçion do server.",
+       "emptyfile": "O file apen-a caregou pâ esee voeuo. Questo poriæ ese dovuo a un aro into nomme do file. Controlla se ti voeu davei caregâ sto file.",
+       "windows-nonascii-filename": "Questo wiki o no supporta di nommi de file con di caratteri speciali.",
+       "fileexists": "Un papê con sto nomme o l'existe za, pe piaxei danni 'n'euggiâ a <strong>[[:$1]]</strong> se no ti t'ê seguo de voeilo cangiâ.\n[[$1|thumb]]",
+       "filepageexists": "A pagina de descriçion de questo file aq l'è za stæta creâ a l'adreçço <strong>[[:$1]]</strong>, sciben che no ghe segge ancon un file con questo nomme. A descriçion de l'oggetto inseia in fase de caregamento a no l'appariâ in scia pagina de descriçion. Pe fâ scì che l'oggetto o comparisce in scia pagina de descriçion, saiâ necessaio modificala manualmente.\n[[$1|thumb]]",
+       "fileexists-extension": "Un file co-in nomme scimile a questo o l'esiste za: [[$2|thumb]]\n* Nomme do file caregou: <strong>[[:$1]]</strong>\n* Nomme do file existente: <strong>[[:$2]]</strong>\nTi voeu miga çerne un nomme ciu caratteristego?",
+       "fileexists-thumbnail-yes": "O file caregou o pâ ese una miniatua ''(thumbnail)''. [[$1|thumb]]\nVerifica, pe confronto, il file <strong>[[:$1]]</strong>.\nSe se tratta da mæxima inmaggine, inte dimenscioin originale, no l'è necessaio caregâne un'atra in miniatua.",
+       "file-thumbnail-no": "O nomme do file comença con <strong>$1</strong>; pâ ch'o segge un'inmaggine de dimenscioin redute ''(miniatua)''.\nSe ti dispon-i del'immaggine inta risoluçion originale, carreghila. Sedunque, pe piaxei, cangighe o nomme.",
+       "fileexists-forbidden": "Un file con questo nomme o l'existe za e o no poeu ese soviascrito. Se ti voeu caregâ o to file, torna inderê e dagghe un atro nomme. [[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "Un file con questo nomme o l'esiste za inte l'archivio de risorse multimediæ condivise. Se ti dexiddei ancon caregâ o file, torna inderê e modifica o nomme co-o quæ caregâ o file. [[File:$1|thumb|center|$1]]",
+       "file-exists-duplicate": "Questo file o l'è un dupricou {{PLURAL:$1|do seguente|di seguenti}} file:",
+       "file-deleted-duplicate": "Un file identico a questo ([[:$1]]) o l'è stæto scassou into passou. Verifica a cronologia de scassatue primma de caregâlo torna.",
+       "file-deleted-duplicate-notitle": "Un file identico a questo o l'è stæto scassou into passou, e o tittolo o l'è stæto soppresso. Domanda a quarcun ch'o g'ha a poscibilitæ de vedde i file soppresci de esaminâ a scituaçion primma de procede torna a-o caregamento.",
+       "uploadwarning": "Avviso de caregamento",
+       "uploadwarning-text": "Pe piaxei modifica chi de sotta a descriçion do file e proeuva torna.",
        "savefile": "Sarva o file",
-       "uploaddisabledtext": "In {{SITENAME}} non se peu caregâ de papê.",
+       "uploaddisabled": "O caregamento di file o l'è disabilitou.",
+       "copyuploaddisabled": "O caricamento tramite URL o l'è disabilitou.",
+       "uploaddisabledtext": "O caricamento di file o l'è disabilitou.",
+       "php-uploaddisabledtext": "O caregamento di file tramite PHP o l'è disabilitou. Controlla a configuaçion de file_uploads.",
+       "uploadscripted": "Questo file o conten un codiçe HTML ò de script, ch'o poriæ ese interpretou erroniamente da un browser web.",
+       "upload-scripted-pi-callback": "Imposcibile caregâ un file ch'o conten un'instruçion de elaboaçion in XML-stylesheet.",
+       "uploaded-script-svg": "Trovou elemento de script \"$1\" into file caregou in formato SVG.",
+       "uploaded-hostile-svg": "Trovou CSS no seguo inte l'elemento de stile do file in formato SVG caregou.",
+       "uploaded-event-handler-on-svg": "Impostâ i attributi de gestion di eventi <code>$1=\"$2\"</code> no l'è consentio inti file SGV",
+       "uploaded-href-attribute-svg": "i attributi href inti file SVG poeuan collegâse solo verso e destinaçioin http:// o https://, trovou <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Trovou href a dæti non segui: destinaçion URI <code>&lt;$1 $2=\"$3\"&gt;</code> caregou into file SVG",
+       "uploaded-animate-svg": "Trovou o tag \"animate\" ch'o poriæ cangiâ href, doeuviando l'attributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> into file SVG caregou.",
+       "uploaded-setting-event-handler-svg": "A configuaçion di attributi pe-o gestô di eventi a l'è bloccâ, trovou <code>&lt;$1 $2=\"$3\"&gt;</code> into file SVG caregou.",
+       "uploaded-setting-href-svg": "L'utilizzo do tag \"set\" pe azonze l'attributo \"href\" a l'elemento parentâ o l'è bloccou.",
+       "uploaded-wrong-setting-svg": "L'uso de l'elemento \"set\" pe azonze una destinaçion remote/data/script pe qua-se-sæ attributo o l'è bloccou. Trovou <code>&lt;set to=\"$1\"&gt;</code> into file SVG caregou.",
+       "uploaded-setting-handler-svg": "o SVG ch'o l'imposta l'attributo \"handler\" con remote/data/script o l'è bloccou. Trovou <code>$1=\"$2\"</code>into file SVG caregou.",
+       "uploaded-remote-url-svg": "o SVG ch'o l'imposta qua-se-sæ attributo de stile con di URL remoti o l'è bloccato. Trovou <code>$1=\"$2\"</code> into file SVG caregou.",
+       "uploaded-image-filter-svg": "Trovou filtro immaggine con URL: <code>&lt;$1 $2=\"$3\"&gt;</code> into file in formato SVG caregou.",
+       "uploadscriptednamespace": "Questo file SVG o conten un namespace '$1' non consentio",
+       "uploadinvalidxml": "O codiçe XML into file caregou o no poeu ese elaboou.",
        "uploadvirus": "Questo file o conten un virus! Dettaggi: $1",
+       "uploadjava": "Questo file o l'è un file ZIP ch'o conten un file .class Java.\nCaregâ i file Java no l'è consentio, perché poeuan caosâ l'aggiamento de restriçioin de segueçça.",
+       "upload-source": "File de origine",
        "sourcefilename": "Nomme do file d'origgine:",
+       "sourceurl": "URL de origine:",
        "destfilename": "Nomme do file de destinassion:",
+       "upload-maxfilesize": "Dimenscion mascima do file: $1",
+       "upload-description": "Descriçion do file",
+       "upload-options": "Opçioin de caregamento",
+       "watchthisupload": "Metti sotta oservaçion",
+       "filewasdeleted": "Un file con questo nomme o l'è stæto za caregou e scassou into passou. Controlla $1 primma de caregâlo torna.",
+       "filename-thumb-name": "Sto chì o pâ un tittolo da miniatua. Pe piaxei no stanni a caregâ e miniatue in scia mæxima wiki. O dunque, corezi o nomme do file de moddo ch'o segge ciù scignificativo e o no l'agge o prefisso da miniatua.",
+       "filename-bad-prefix": "O nomme do file che t'ê aproeuvo a caregâ o comença con '''\"$1\"''', ch'o l'è un nomme generico scimile a quelli assegnæ aotomaticamente da-e fotocammie digitale. Pe piaxei çerni un nomme ciù descrittivo pe-o to file.",
+       "upload-proto-error": "Protocollo errou",
+       "upload-proto-error-text": "Pe l'upload remoto l'è necessaio speçificâ di URL che començan con <code>http://</code> oppû <code>ftp://</code>.",
        "upload-file-error": "Errô interno",
+       "upload-file-error-text": "S'è veificou un errô interno durante a creaçion de 'n file temporannio in sciô server. Contatta un [[Special:ListUsers/sysop|amministratô]].",
+       "upload-misc-error": "Errô de caregamento sconosciuo",
+       "upload-misc-error-text": "S'è veificou un errô non identificou durante o caregamento do file. Controlla che a URL a segge corretta e accescibile e proeuva torna. Se o problema o persciste, contatta un [[Special:ListUsers/sysop|amministratô]].",
+       "upload-too-many-redirects": "L'URL o contegniva troppi redirect",
+       "upload-http-error": "S'è verificou un errô HTTP: $1",
+       "upload-copy-upload-invalid-domain": "No l'è consentio o caregamento de coppie da questo dominnio.",
+       "upload-foreign-cant-upload": "Questo wiki o no l'è configuou pe caregâ i file into repository de file esterno domandou.",
+       "upload-dialog-disabled": "O caregamento di file tramite questo barcon de dialogo o l'è disabilitou inte questo wiki.",
+       "upload-dialog-title": "Carrega file",
+       "upload-dialog-button-cancel": "Anulla",
+       "upload-dialog-button-done": "Fæto",
+       "upload-dialog-button-save": "Sarva",
+       "upload-dialog-button-upload": "Carrega",
+       "upload-form-label-infoform-title": "Detaggi",
+       "upload-form-label-infoform-name": "Nomme",
+       "upload-form-label-infoform-name-tooltip": "Un tittolo unnico e descritivo pe-o file, ch'o serviâ da nomme. Doeuviâ pure e toeu parolle e i spaççi. No stagh'a mette l'estenscion.",
+       "upload-form-label-infoform-description": "Descriçion",
+       "upload-form-label-infoform-description-tooltip": "Descrivi scinteticamente tutto quanto sæ degno de notta a propoxito de quest'oeuvia.\nPe-e foto, indica e cose prinçipæ che gh'en rappresentæ, l'öcaxon e/ò o posto.",
+       "upload-form-label-usage-title": "Utilizzo",
+       "upload-form-label-usage-filename": "Nomme do file",
+       "upload-form-label-own-work": "Questo o l'è travaggio mæ",
+       "upload-form-label-infoform-categories": "Categorie",
+       "upload-form-label-infoform-date": "Dæta",
+       "upload-form-label-own-work-message-generic-local": "Confermo che son aproeuvo a caregâ sto file segondo e condiçioin de serviçio e e polittiche in sce e liçençe de {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-generic-local": "Se non t'ê in grou de caregâ o file segondo e politiche de {{SITENAME}}, særa sto barcon e proeuva un atro mettodo.",
+       "upload-form-label-not-own-work-local-generic-local": "Proeuva ascì a [[Special:Upload|pagina de caregamento predefinia]].",
+       "upload-form-label-own-work-message-generic-foreign": "Ho acapio che son aproeuvo a caregâ questo file inte 'n archivio condiviso. Confermo che-o façço segondo e so condiçioin de serviççio e-e so polittiche in sce e liçençe.",
+       "upload-form-label-not-own-work-message-generic-foreign": "Se non t'ê in grou de caregâ o file segondo e politiche de l'archivvio condiviso, særa sto barcon e proeuva un atro mettodo.",
+       "upload-form-label-not-own-work-local-generic-foreign": "Ti poeu provâ ascì a doeuviâ a [[Special:Upload|pagina de caregamento insce {{SITENAME}}]], se questo file o poeu ese caregou segondo e soeu politiche.",
+       "backend-fail-stream": "Imposcibile trasmette o file $1.",
+       "backend-fail-backup": "Imposcibile eseguî o backup do file $1 .",
+       "backend-fail-notexists": "O file $1 o no l'existe.",
+       "backend-fail-hashes": "Imposcibile ötegnî l'hash di file pe 'n confronto.",
+       "backend-fail-notsame": "Existe za un file non identico a \"$1\".",
+       "backend-fail-invalidpath": "$1 o no l'è un percorso de archiviaçion vallido.",
+       "backend-fail-delete": "Imposcibile scassâ o file $1.",
+       "backend-fail-describe": "Imposcibile modificâ i metadæti do file \"$1\".",
+       "backend-fail-alreadyexists": "O file $1 o l'existe za.",
+       "backend-fail-store": "Imposcibbile memorizzâ o file  $1  in  $2 .",
+       "backend-fail-copy": "Imposcibile copiâ o file  $1  in  $2 .",
+       "backend-fail-move": "Imposcibile messciâ o file  $1  in  $2 .",
+       "backend-fail-opentemp": "Imposcibbile arvî o file temporannio.",
+       "backend-fail-writetemp": "Imposcibbile scrive o file temporannio.",
+       "backend-fail-closetemp": "Imposcibbile serâ o file temporannio.",
+       "backend-fail-read": "Imposcibile leze o file  $1 .",
+       "backend-fail-create": "Imposcibile scrive o file $1.",
+       "backend-fail-maxsize": "Imposcibile scrive o file $1 perché o l'è ciù grande de {{PLURAL:$2|un|$2}} byte.",
+       "backend-fail-readonly": "O backend de memoia \"$1\" o l'è attualmente de sola lettua. A raxon indicâ a l'è: <em>$2</em>",
+       "backend-fail-synced": "O file \"$1\" o l'è inte 'n stato non coerente inti backend de memoia interna.",
+       "backend-fail-connect": "Imposcibile connettise a-o backend de memoia \"$1\".",
+       "backend-fail-internal": "S'è verificou un errô sconosciuo into backend de memoia \"$1\".",
+       "backend-fail-contenttype": "Imposcibile determinâ a tipologia do file da archiviâ inte \"$1\".",
+       "backend-fail-batchsize": "O backend de memoia o l'ha programmou una serie de $1 {{PLURAL:$1|opiaçion|opiaçioin}} sciu file; o limmite o l'è de $2 {{PLURAL:$2|opiacion|opiacioin}}.",
+       "backend-fail-usable": "Imposcibile leze ò scrive o file \"$1\" a caosa de aetorizzaçioin insuffixenti ò directory/contegnitoî mancanti.",
+       "filejournal-fail-dbconnect": "Imposcibile connettise a-o database journal pe l'archiviaçion back-end \"$1\".",
+       "filejournal-fail-dbquery": "Imposcibile aggiornâ o database journal pe l'archiviaçion back-end \"$1\".",
+       "lockmanager-notlocked": "Imposcibile sbloccâ \"$1\"; o no l'è bloccou.",
+       "lockmanager-fail-closelock": "Imposcibbile serâ o file de blocco pe \"$1\".",
+       "lockmanager-fail-deletelock": "Imposcibile scassâ o file de blocco pe $1.",
+       "lockmanager-fail-acquirelock": "Imposcibbile aquixî o blocco pe $1.",
+       "lockmanager-fail-openlock": "Imposcibbile arvî o file de blocco pe \"$1\".",
+       "lockmanager-fail-releaselock": "Imposcibile revocâ o blocco pe $1.",
+       "lockmanager-fail-db-bucket": "Imposcibile contattâ i necessai database de blocco into bucket $1.",
+       "lockmanager-fail-db-release": "Imposcibile revocâ i blocchi in sciô database $1.",
+       "lockmanager-fail-svr-acquire": "Imposcibile acquixî i blocchi in sciô server $1.",
+       "lockmanager-fail-svr-release": "Imposcibile revocâ i blocchi in sciô server $1.",
+       "zip-file-open-error": "S'è verificou 'n errô durante l'avertua do file pe-i controlli ZIP.",
+       "zip-wrong-format": "O file specificou o no l'ea un file ZIP.",
+       "zip-bad": "O file o l'è un file ZIP corrotto ò atrimenti illezibbile.\nO no poeu ese controllou comme se dè pe-a segueçça.",
+       "zip-unsupported": "O file o l'è un file ZIP ch'o l'adoeuvia de caratteristeghe ZIP non supportæ da MediaWiki.\nO no poeu ese ben controllou pe-a segueçça.",
+       "uploadstash": "Carrega stash",
+       "uploadstash-summary": "Questa pagina a consente l'accesso a-i file che son stæti caregæ (o son in fase de caregamento) ma che n'en ancon stæti pubbricæ in sciô wiki. Questi file son vixibbili solo a l'utente ch'o i ha caregæ.",
+       "uploadstash-clear": "Elimmina i file in stash",
+       "uploadstash-nofiles": "No ti g'hæ de file into stash.",
+       "uploadstash-badtoken": "Esecuçion de l'açion non riuscia, foscia perché e to credençiale de modiffica son descheite. Proeuva ancon.",
+       "uploadstash-errclear": "O nettezzo di file o no l'è ariescio.",
+       "uploadstash-refresh": "Aggiorna l'elenco di file",
+       "uploadstash-thumbnail": "veddi miniatua",
+       "invalid-chunk-offset": "Offset d'a parte non vallido.",
+       "img-auth-accessdenied": "Accesso negou",
+       "img-auth-nopathinfo": "PATH_INFO mancante.\nO server o no l'è impostou pe passâ quest'informaçion.\nO poriæ ese basou insce CGI e o no poeu supportâ img_auth.\nAmia https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-notindir": "O percorso domandou o no l'è inta directory de upload configuâ.",
+       "img-auth-badtitle": "Imposcibile construe un tittolo vallido da \"$1\".",
+       "img-auth-nologinnWL": "No t'ê introu e \"$1\" o no l'è inta whitelist.",
+       "img-auth-nofile": "O file \"$1\" o no l'existe.",
+       "img-auth-isdir": "Ti çerchi d'accede a 'na directory \"$1\".\nL'è consentio solo l'accesso a-i file.",
+       "img-auth-streaming": "\"$1\" in streaming.",
+       "img-auth-public": "La fonçion de img_auth.php a l'è de dâ in output di file da un scito wiki privou.\nQuesto scito o l'è configuou comme un wiki pubbrico.\nPe 'na segueçça ottimale, img_auth.php o l'è disattivou.",
+       "img-auth-noread": "L'utente o no g'ha accesso a-a lettua de \"$1\".",
+       "http-invalid-url": "URL non vallido: $1",
+       "http-invalid-scheme": "Di URL co-o prefisso \"$1\" no son supportæ.",
+       "http-request-error": "Recesta HTTP fallia a caosa de 'n aro sconosciuo.",
+       "http-read-error": "Errô de lettua HTTP.",
+       "http-timed-out": "Recesta HTTP descheita.",
+       "http-curl-error": "Errô durante o recuppero de l'URL: $1",
+       "http-bad-status": "S'è verificou un problema durante a recesta HTTP: $1 $2",
+       "upload-curl-error6": "URL no razonzibbile",
+       "upload-curl-error6-text": "Imposcibile razonze a URL specificâ. Verifica che a URL a sæ scrita correttamente e che o scito in question o sæ attivo.",
+       "upload-curl-error28": "Tempo descheito pe l'upload",
+       "upload-curl-error28-text": "O scito remoto o l'ha impiegou troppo tempo a risponde. Verifica che o sito o sæ attivo, attendi quarche menuto e proeuva torna, se mai inte 'n momento con meno traffego.",
        "license": "Licensa:",
        "license-header": "Licensa",
        "nolicense": "Nisciûnn-a liçensa indicâa",
+       "licenses-edit": "Modiffica opçioin de liçença",
+       "license-nopreview": "(Anteprimma non disponibbile)",
+       "upload_source_url": "(un file da un URL vallido e accescibile pubbricamente)",
+       "upload_source_file": "(un file da-o to computer)",
+       "listfiles-delete": "scassa",
+       "listfiles-summary": "Questa pagina speciale a mostra tutti i file caregæ.",
        "listfiles_search_for": "Çerca pe nomme de l'imàgine:",
+       "listfiles-userdoesnotexist": "L'utença \"$1\" a no l'è registrâ.",
        "imgfile": "file",
        "listfiles": "Lista d'archivvi",
+       "listfiles_thumb": "Miniatua",
        "listfiles_date": "Dæta",
+       "listfiles_name": "Nomme",
+       "listfiles_user": "Utente",
+       "listfiles_size": "Dimenscion",
+       "listfiles_description": "Descriçion",
+       "listfiles_count": "Verscioin",
+       "listfiles-show-all": "Includdi e vege verscioin de inmaggine",
+       "listfiles-latestversion": "Verscion corente",
+       "listfiles-latestversion-yes": "Sci",
+       "listfiles-latestversion-no": "No",
        "file-anchor-link": "file",
        "filehist": "Stöia do file",
        "filehist-help": "Sciacca insce dæta/ôa pe amiâ o file comm'o s'apresentâva into momento indicòu.",
+       "filehist-deleteall": "scassa tutto",
+       "filehist-deleteone": "scassa",
        "filehist-revert": "Ripristina",
        "filehist-current": "Corrente",
        "filehist-datetime": "Dæta/Ôa",
        "filehist-thumb": "Miniatua",
        "filehist-thumbtext": "Miniatua da versción de $1",
+       "filehist-nothumb": "Nisciun-a miniatua",
        "filehist-user": "Utente",
        "filehist-dimensions": "Dimenscioin",
        "filehist-filesize": "Dimension de l'archivvio",
        "filehist-comment": "Coménti",
        "imagelinks": "Ûzo do file",
        "linkstoimage": "{{PLURAL:$1|A segoente pàgina a contegne|E segoenti $1 pàgine contegnan}} colegaménti a-o file:",
+       "linkstoimage-more": "Ciù de $1 {{PLURAL:$1|pagina aponta|pagine apontan}} a questo file.\nA seguente lista a mostra {{PLURAL:$1|a primma paggina ch'a l'aponta|e primme $1 paggine ch'apontan}} a sto file.\nL'è disponibile un [[Special:WhatLinksHere/$2|elenco completo]].",
        "nolinkstoimage": "No gh'è nisciûnn-a pàgina collegâ con 'sto file.",
-       "sharedupload": "'St'archivvio o l'è condiviso; sajeiva a dî c'o pêu ese dêuviòu da ciû progetti wiki.",
+       "morelinkstoimage": "Vixualizza [[Special:WhatLinksHere/$1|di atri inganci]] a questo file.",
+       "linkstoimage-redirect": "$1 (rendriççamento file) $2",
+       "duplicatesoffile": "{{PLURAL:$1|O seguente file o l'è un dupricou|I seguenti $1 file son di dupricæ}} de questo file ([[Special:FileDuplicateSearch/$2|urteioî detaggi]]):",
+       "sharedupload": "Questo file o proven da $1 e o poeu ese doeuviou da di atri progetti.",
+       "sharedupload-desc-there": "Questo file o proven da $1 e o poeu ese doeuviou da di atri progetti.\nConsurta a [$2 pagina de descriçion do file] pe di urteioî informaçioin.",
        "sharedupload-desc-here": "Sto file o vegne da $1 e o peu êse dêuviòu inti âtri progetti.\nChì apreuvo ti peu védde a descriçión inta [$2 pàgina de descriçión do file].",
+       "sharedupload-desc-edit": "Questo file o proven da $1 e o poeu ese doeuviou da di atri progetti.\nFoscia ti voeu modificâ a descriçion presente inta [$2 pagina de descriçion do file].",
+       "sharedupload-desc-create": "Questo file o proven da $1 e o poeu ese doeuviou da di atri progetti.\nFoscia ti voeu modificâ a descriçion presente inta [$2 pagina de descriçion do file].",
+       "filepage-nofile": "No existe un file con sto nomme.",
+       "filepage-nofile-link": "No existe un file con sto nomme, ma l'è poscibile [$1 caregâlo].",
        "uploadnewversion-linktext": "Carrega 'na neuva verscion de sto file",
+       "shared-repo-from": "da $1",
+       "shared-repo": "un archivio condiviso",
        "upload-disallowed-here": "Imposcibbile sorvescrive sto file.",
+       "filerevert": "Ripristina $1",
+       "filerevert-legend": "Ripristina file",
+       "filerevert-intro": "Ti stæ pe ripristinâ o file '''[[Media:$1|$1]]''' a-a [$4 verscion do $2, $3].",
+       "filerevert-comment": "Raxon:",
+       "filerevert-defaultcomment": "Ripristinou a verscion do $2, $1 ($3)",
+       "filerevert-submit": "Ripristina",
+       "filerevert-success": "'''O file [[Media:$1|$1]]''' o l'è stæto ripristinou a-a [$4 verscion do $2, $3].",
+       "filerevert-badversion": "No gh'è de verscioin locali precedenti do file co-o timestamp provisto.",
+       "filedelete": "Scassa \"$1\"",
+       "filedelete-legend": "Scassa o file",
+       "filedelete-intro": "Ti stæ pe scassâ o file '''[[Media:$1|$1]]''' con tutta a so cronologia.",
+       "filedelete-intro-old": "T'ê aproeuvo a scassâ a vercsion de '''[[Media:$1|$1]]''' do [$4 $2, $3].",
+       "filedelete-comment": "Raxon:",
        "filedelete-submit": "Scassa",
+       "filedelete-success": "O file '''$1''' o l'è stæto scassou.",
+       "filedelete-success-old": "A verscion do file '''[[Media:$1|$1]]''' do $2, $3  a l'è stæta scassaa.",
+       "filedelete-nofile": "'''$1''' o no l'existe.",
+       "filedelete-nofile-old": "Verscioin d'archivio de '''$1''' co-e caratteristeghe indicæ no ghe n'è.",
+       "filedelete-otherreason": "Atra motivaçion ò motivaçion azontiva:",
+       "filedelete-reason-otherlist": "Un'atra raxon",
+       "filedelete-reason-dropdown": "*Raxoin comun-e de scançellaçion\n** Violaçion do drito d'aotô\n** File dupricou",
+       "filedelete-edit-reasonlist": "Modiffica e raxoin da scassatua",
+       "filedelete-maintenance": "Scançellaçion e ricuppero di file temporaniamente disattivæ durante a manutençion.",
+       "filedelete-maintenance-title": "Imposcibbile eliminâ o file",
        "mimesearch": "Çerca MIME",
+       "mimesearch-summary": "Questa pagina a consente de filtrâ i file in base a-o tipo MIME.\nInsei a stringa de riçerca inta forma tipo/sottotipo o tipo/*, pr'es. <code>image/jpeg</code>.",
+       "mimetype": "Tipo MIME:",
+       "download": "scarrega",
+       "unwatchedpages": "Paggine non öservæ",
        "listredirects": "Lista de rindirissamenti",
+       "listduplicatedfiles": "Lista di file doggi",
+       "listduplicatedfiles-summary": "Questo o l'è un elenco di file, donde a verscion ciù reçente de 'n file a l'è un dupricou da verscion ciù reçente de 'n atro file. Se piggia in  conscideraçion solo che i file locali.",
+       "listduplicatedfiles-entry": "[[:File:$1|$1]] o g'ha [[$3|{{PLURAL:$2|un duplicou|$2 duplicæ}}]].",
        "unusedtemplates": "Template no ûtilissæ",
+       "unusedtemplatestext": "Inte sta pagina l'è elencou e pagine do namespace {{ns:template}} che no son incluse inte nisciun-a pagina. Primma de scassâle l'è öportun veificâ che i scingoli template no g'aggian di atri collegamenti intranti.",
+       "unusedtemplateswlh": "atri collegamenti",
        "randompage": "Pagina a brettìo",
+       "randompage-nopages": "Pagine {{PLURAL:$2|into seguente|inti seguenti}} namespace no ghe n'è: $1.",
+       "randomincategory": "Pagina a brettio inta categoria",
+       "randomincategory-invalidcategory": "\"$1\" o no l'è un nomme de categoria vallido.",
+       "randomincategory-nopages": "Paggine in [[:Category:$1]] no ghe n'è.",
+       "randomincategory-category": "Categoria:",
+       "randomincategory-legend": "Pagina a brettio inta categoria",
+       "randomincategory-submit": "Vanni",
        "randomredirect": "Ûn rindirissamento a brettîo",
+       "randomredirect-nopages": "Into namespace \"$1\" redirect no ghe n'è.",
        "statistics": "Statistiche",
+       "statistics-header-pages": "Statistiche de pagine",
+       "statistics-header-edits": "Statistiche de modifiche",
+       "statistics-header-users": "Statistiche di utenti",
+       "statistics-header-hooks": "Atre statistiche",
+       "statistics-articles": "Paggine de contegnui",
+       "statistics-pages": "Paggine",
+       "statistics-pages-desc": "Tutte e paggine do scito, compreiso e paggine de discuscion, i redirect, etç.",
+       "statistics-files": "File caregæ",
+       "statistics-edits": "Modifiche a partî dal l'installaçion de {{SITENAME}}",
+       "statistics-edits-average": "Meddia de modiffiche pe paggina",
+       "statistics-users": "[[Special:ListUsers|Utenti]] registræ",
+       "statistics-users-active": "Utenti attivi",
+       "statistics-users-active-desc": "Utenti che han effettuou un'açion {{PLURAL:$1|inte l'urtimo giorno|inti urtimi $1 giorni}}",
+       "pageswithprop": "Paggine co-ina propietæ de paggina",
+       "pageswithprop-legend": "Paggine co-ina propietæ de paggina",
+       "pageswithprop-text": "Questa pagina a fa 'na lista de paggine ch'adoeuvian una particolâ propietæ de paggina.",
+       "pageswithprop-prop": "Nomme da propietæ:",
+       "pageswithprop-submit": "Vanni",
+       "pageswithprop-prophidden-long": "valô testoale longo da propietæ ascoso ($1)",
+       "pageswithprop-prophidden-binary": "valô binaio da propietæ ascoso ($1)",
        "doubleredirects": "Rindirissamenti doggi",
+       "doubleredirectstext": "In questa pagina gh'è elencou e paggine che rendiriççan a di atre paggine de redirect.\nOgni riga a conten i collegamenti a-o primmo e a-o segondo redirect, oltre a-a primma riga de testo do segondo redirect che a l'uso o conten a paggina de destinaçion \"corretta\" a-a quæ doviæ puntâ o primmo redirect ascì.\nI redirect <del>scassæ</del> son stæti corretti.",
+       "double-redirect-fixed-move": "[[$1]] o l'è stæto mesciou.\nO l'è stato aggiornou aotomaticamente e oua o l'è un redirect a [[$2]].",
+       "double-redirect-fixed-maintenance": "Corretto aotomaticamente o redirect doggio da [[$1]] a [[$2]] into travaggio de manutençion.",
+       "double-redirect-fixer": "Correttô di redirect",
        "brokenredirects": "Rindirissamenti sballiæ",
-       "brokenredirectstext": "De sotta unn-a lista de reindirissi a pagine che non existàn:",
+       "brokenredirectstext": "I rendriççi chì de sotta colegan a de paggine inexistente:",
        "brokenredirects-edit": "cangia",
        "brokenredirects-delete": "scassa",
        "withoutinterwiki": "Paggine sensa interwiki",
        "withoutinterwiki-summary": "'Ste paggine chì inzû no g'han nisciûn collegamento co-e verscioîn in âtre lengoe:",
+       "withoutinterwiki-legend": "Prefisso",
+       "withoutinterwiki-submit": "Mostra",
        "fewestrevisions": "Voxi con meno revixoîn",
        "nbytes": "$1 {{PLURAL:$1|byte|byte}}",
+       "ncategories": "$1 {{PLURAL:$1|categoria|categorie}}",
+       "ninterwikis": "$1 {{PLURAL:$1|interwiki}}",
        "nlinks": "$1 {{PLURAL:$1|collegamento|collegamenti}}",
        "nmembers": "$1 {{PLURAL:$1|elemento|elementi}}",
+       "nmemberschanged": "$1 → $2 {{PLURAL:$2|elemento|elementi}}",
+       "nrevisions": "$1 {{PLURAL:$1|revixon|revixoin}}",
+       "nimagelinks": "Doeuviou inte $1 {{PLURAL:$1|paggina|paggine}}",
+       "ntransclusions": "Doeuviou inte $1 {{PLURAL:$1|paggina|paggine}}",
+       "specialpage-empty": "Questa paggina speciale a l'è attualmente voeua.",
        "lonelypages": "Paggine orfane",
+       "lonelypagestext": "E seguente paggine no son incluse ni colegæ a di atre paggine de {{SITENAME}}.",
        "uncategorizedpages": "Paggine sensa categorîa",
        "uncategorizedcategories": "Categorîe sensa categorîa",
        "uncategorizedimages": "Immaggini sensa categorîa",
        "unusedimages": "Archivvi no ûtilissæ",
        "wantedcategories": "Categorîe domandæ",
        "wantedpages": "Paggine domandæ",
+       "wantedpages-summary": "Lista de paggine inexistente co-o ciu gran nummero de collegamenti a lô, escludendo e pagine ch'han solo che i rendiriççi che-e collegan. Pe 'n elenco de pagine inexistente che g'han di rendriççi che-e collegan, amia [[{{#special:BrokenRedirects}}|a lista di rendriççi erræ]].",
+       "wantedpages-badtitle": "Tittolo invallido into groppo di risultæ: $1",
+       "wantedfiles": "File domandæ",
+       "wantedfiletext-cat": "I seguenti file son in doeuvia, ma no existan. I file ospitæ inte di repository esterni porieivan esighe elencæ sciben che existan. Questi fasci poxitivi saian <del>barræ</del>. E pagine che incòrpoan i file che no existan son elencæ in [[:$1]].",
+       "wantedfiletext-cat-noforeign": "I seguenti file son in doeuvia, ma no existan. Inoltre, e pagine che incòrpoan questi file son elencæ inta [[:$1]].",
+       "wantedfiletext-nocat": "I seguenti file son reciamæ da wikilink, ma no existan. I file ospitæ inte di repository esterni porieivan ese elencæ sciben existenti. Questi fasci poxitivi saian <del>barræ</del>.",
+       "wantedfiletext-nocat-noforeign": "I seguenti file son in doeuvia, ma no existan.",
+       "wantedtemplates": "Template domandæ",
        "mostlinked": "Paggine ciû collegæ",
        "mostlinkedcategories": "Categorîe ciû collegæ",
-       "mostlinkedtemplates": "Template ciû dêuviæ",
+       "mostlinkedtemplates": "Paggine ciu incluse",
        "mostcategories": "Voxi con ciû categorîe",
        "mostimages": "Immaggini con ciû collegamenti",
+       "mostinterwikis": "Paggine con ciu interwiki",
        "mostrevisions": "Voxi con ciû revixoîn",
        "prefixindex": "Indiçe arfabetico de voxe",
+       "prefixindex-namespace": "Tutte e paggine co-o prefisso do namespace $1",
+       "prefixindex-submit": "Mostra",
+       "prefixindex-strip": "Ascondi o prefisso inta lista",
        "shortpages": "Paggine ciû cûrte",
        "longpages": "Paggine ciû longhe",
        "deadendpages": "Paggine sensa sciortîa",
+       "deadendpagestext": "E seguente paggine no son collegæ a di atre paggine de {{SITENAME}}.",
        "protectedpages": "Paggine protette",
+       "protectedpages-indef": "Solo proteçioin indefinie",
+       "protectedpages-summary": "Questa paggina a l'elenca e paggine existente ch'en attoalmente protezue. Pe 'n elenco di tittoli protezui da-a creaçion, amia [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
+       "protectedpages-cascade": "Solo proteçioin ricorscive",
+       "protectedpages-noredirect": "Ascondi redirect",
+       "protectedpagesempty": "Paggine protette con sti parametri pe-o momento no ghe n'è.",
+       "protectedpages-timestamp": "Dæta e oa",
+       "protectedpages-page": "Paggina",
+       "protectedpages-expiry": "Scadença",
+       "protectedpages-performer": "Protetta da l'utente",
+       "protectedpages-params": "Parammetri de proteçion",
+       "protectedpages-reason": "Raxon",
+       "protectedpages-submit": "Mostra paggine",
+       "protectedpages-unknown-timestamp": "Sconosciuo",
+       "protectedpages-unknown-performer": "Utente sconosciuo",
        "protectedtitles": "Tittoli protezûi",
+       "protectedtitles-summary": "Questa pagina a l'elenca i titoli che son attualmente protetti da-a creaçion. Pe 'n elenco de pagine existente che son protette, amia [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
+       "protectedtitlesempty": "Tittoli protezui con sti parammetri pe-o momento no ghe n'è.",
+       "protectedtitles-submit": "Mostra tittoli",
        "listusers": "Lista d'ûtenti",
+       "listusers-editsonly": "Mostra solo i utenti con di contributi",
+       "listusers-creationsort": "Ordina pe dæta de creaçion",
+       "listusers-desc": "Ordina in senso decrescente",
+       "usereditcount": "$1 {{PLURAL:$1|contributo|contributi}}",
        "usercreated": "{{GENDER:$3|Creòu/â}} o $1 a-a $2",
        "newpages": "Pagine ciù reçenti",
+       "newpages-submit": "Mostra",
+       "newpages-username": "Nomme utente",
        "ancientpages": "Paggine ciû vëgie",
        "move": "Mescia",
        "movethispage": "Mescia 'sta paggina",
+       "unusedimagestext": "I seguenti file existan ma no son doeuviæ inte nisciun-a paggina.\nNotta che di atri sciti web porieivan ese colegæ a 'n file co-in URL diretto, e coscì o poriæ ese inte sta lista sciuben ch'o segge in doeuvia.",
+       "unusedcategoriestext": "E seguente paggine de categoria existan, sciben che nisciun'atra paggina o categoria a-e doeuvie.",
+       "notargettitle": "Dæti mancanti",
+       "notargettext": "No t'hæ indicou una pagina o un utente con chi eseguî sta fonçion.",
+       "nopagetitle": "A pagina de destinaçion a no l'existe",
+       "nopagetext": "A pagina domandâ a no l'existe.",
        "pager-newer-n": "{{PLURAL:$1|1 ciù nêuvo|$1 ciù nêuvi}}",
        "pager-older-n": "{{PLURAL:$1|1 ciù vêgio|$1 ciù vêgi}}",
+       "suppress": "Soprimmi",
+       "querypage-disabled": "Questa pagina speciale a l'è disattivâ pe motivi de prestaçion.",
+       "apihelp": "Agiutto API",
+       "apihelp-no-such-module": "Moddulo \"$1\" non trovou.",
+       "apisandbox": "Paggina de proeuva API",
+       "apisandbox-jsonly": "Pe doeuviâ a paggina de proeuva API ghe voeu o JavaScript.",
+       "apisandbox-api-disabled": "E fonçionalitæ API son disabilitæ insce questo scito.",
+       "apisandbox-intro": "Doeuvia sta paggina pe fâ prattica co-e <strong>API web service MediaWiki</strong>.\nPe di urteioî detaggi de utilizzo de API, amia a [[mw:API:Main page|documentaçion API]]. Exempio: [https://www.mediawiki.org/wiki/API#A_simple_example ötegnî o contegnuo da paggina prinçipâ]. Seleçion-a un'açion pe vedde di atri exempi.\n\nNotta che, sciben che questa a segge 'na paggina pe-e proeuve, i açioin che ti esegui chì porieivan modificâ a wiki.",
+       "apisandbox-fullscreen": "Espandi pannello",
+       "apisandbox-fullscreen-tooltip": "Espandi o pannello sandbox pe impî o barcon do browser.",
+       "apisandbox-unfullscreen": "Mostra a pagina",
+       "apisandbox-unfullscreen-tooltip": "Reduxi o pannello sandbox, coscì che i collegamenti de navigaçion MediaWiki seggian disponibbili.",
+       "apisandbox-submit": "Inandia recesta",
+       "apisandbox-reset": "Nettezza",
+       "apisandbox-retry": "Ritenta",
+       "apisandbox-loading": "Caregamento de informaçioin pe-o moddulo API \"$1\"...",
+       "apisandbox-load-error": "S'è veificou un errô durante o caregamento de informaçioin pe-o moddulo API \"$1\": $2",
+       "apisandbox-no-parameters": "Questo modulo API o no g'ha de parammetri.",
+       "apisandbox-helpurls": "Collegamenti a-a guidda",
+       "apisandbox-examples": "Exempi",
+       "apisandbox-dynamic-parameters": "Parammetri azontivi",
+       "apisandbox-dynamic-parameters-add-label": "Azonzi parammetro:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nomme do parammetro",
+       "apisandbox-dynamic-error-exists": "Un parammetro denominou \"$1\" o l'existe za.",
+       "apisandbox-deprecated-parameters": "Parammetri sconsegiæ",
+       "apisandbox-fetch-token": "Aoto-compilla o token",
+       "apisandbox-submit-invalid-fields-title": "Gh'è di campi che n'en vallidi",
+       "apisandbox-submit-invalid-fields-message": "Correzi i campi evidençiæ e riproeuva.",
+       "apisandbox-results": "Risultæ",
+       "apisandbox-sending-request": "Invio recesta de API...",
+       "apisandbox-loading-results": "Riceçion di risultæ de API in corso...",
+       "apisandbox-results-error": "S'è veificou un errô durante o caregamento da risposta a l'interrogaçion API: $1",
+       "apisandbox-request-url-label": "URL de recesta:",
+       "apisandbox-request-time": "Tempo richiesto: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Correzi token e reinvia",
+       "apisandbox-results-fixtoken-fail": "Imposcibile recuperâ o token \"$1\".",
+       "apisandbox-alert-page": "I campi insce questa pagina no son vallidi.",
+       "apisandbox-alert-field": "O valô de questo campo o no l'è vallido.",
        "booksources": "Fonte libraie",
        "booksources-search-legend": "Çerca e fonti",
        "booksources-isbn": "Codice ISBN:",
        "booksources-search": "Çerca",
        "booksources-text": "De sotta unn-a lista de inganci a di ätri sciti che vendan libbri neuvi e vegi e che porrieivan avei ciu informaçioin in scî libbri che ti te çerchi",
-       "specialloguserlabel": "Ûtente:",
-       "speciallogtitlelabel": "Tittolo:",
+       "booksources-invalid-isbn": "O ISBN inserio pâ no ese vallido; controlla che no ghe segge stæto di ari into copiâlo da-a fonte originale.",
+       "specialloguserlabel": "Açion effettuâ da:",
+       "speciallogtitlelabel": "Açion effettuâ sciu (tittolo da paggina ò {{ns:user}}:Nomme utente):",
        "log": "Log",
-       "all-logs-page": "Tûtti i registri",
-       "alllogstext": "Presentaçion unega de tutti i registri do scito {{SITENAME}}.\nTi te peu strinza a vista se ti te çerni un tipo de registro, un nomme de un utente o de pagina.",
+       "logeventslist-submit": "Mostra",
+       "all-logs-page": "Tutti i registri pubbrichi",
+       "alllogstext": "Presentaçion combinaa de tutti i registri de {{SITENAME}}.\nL'è poscibile restrenze i critei de riçerca seleçionando o tipo de registro, l'utente ch'o l'ha eseguio l'açion, e/ò a pagina interessâ (entrambi i campi son senscibbili a-o maiuscolo/minuscolo).",
+       "logempty": "O registro o no conten di elementi corespondenti a-a riçerca.",
+       "log-title-wildcard": "Riçerca di titoli che començan con",
+       "showhideselectedlogentries": "Mostra/ascondi e voxe de registro seleçionæ",
+       "log-edit-tags": "Modifica i etichette de voxe de registro seleçionæ",
+       "checkbox-select": "Seleçion-a: $1",
+       "checkbox-all": "Tutto",
+       "checkbox-none": "Nisciun",
+       "checkbox-invert": "Inverti",
        "allpages": "Tûtte e paggine",
        "nextpage": "Proscima paggina ($1)",
        "prevpage": "Paggina preçedente ($1)",
        "allpagesfrom": "Fanni vedde e paggine comensando da:",
+       "allpagesto": "Mostra e paggine scin a:",
        "allarticles": "Tùtte e pàgine",
        "allinnamespace": "Tutte e pagine ($1 namespace)",
        "allpagessubmit": "Vanni",
        "allpagesprefix": "Fanni vedde e paggine che inissian con:",
        "allpagesbadtitle": "O tittolo dæto a-a paggina o non va ben, òpû o conten di prefissi inter-lengua o inter-wiki. O porriæ ascì contegnî un o ciù caratteri che inti tittoli no se peuan deuviâ.",
        "allpages-bad-ns": "\"$1\" o no ghe in {{SITENAME}}.",
+       "allpages-hide-redirects": "Ascondi i redirect",
+       "cachedspecial-viewing-cached-ttl": "T'ê aproeuvo a 'miâ 'na verscion de sta paggina memorizzâ inta cache, ch'a poeu ese vegia de $1 a-o mascimo.",
+       "cachedspecial-viewing-cached-ts": "T'ê aproeuvo a 'miâ 'na verscion de sta paggina memorizzâ inta cache, ch'a poriæ no ese do tutto aggiornâ.",
+       "cachedspecial-refresh-now": "Mostra a ciù reçente.",
        "categories": "Categorîe",
+       "categories-submit": "Mostra",
+       "categoriespagetext": "{{PLURAL:$1|A seguente categoria a conten|E seguente categorie contengnan}} de pagine o di file murtimediali.\nE [[Special:UnusedCategories|categorie voeue]] no son mostræ chì.\nAmia ascì e [[Special:WantedCategories|categorie richieste]].",
+       "categoriesfrom": "Mostra e categorie a partî da:",
+       "deletedcontributions": "Contributi utente scassæ",
+       "deletedcontributions-title": "Contributi utente scassæ",
+       "sp-deletedcontributions-contribs": "contribuçioin",
+       "linksearch": "Çerchia di inganci esterni",
+       "linksearch-pat": "Pattern de riçerca:",
+       "linksearch-ns": "Namespace:",
+       "linksearch-ok": "Çerca",
+       "linksearch-text": "L'è poscibbile doeuviâ di metacaratteri comme \"*.wikipedia.org\".\nL'è necessaio a-o manco un dominnio di primmo livello, presempio \"*.org\".<br />\n{{PLURAL:$2|Protocollo supportou|Protocolli supportæ}}: $1 (predefinio http:// se no l'è specificou nisciun protocollo).",
        "linksearch-line": "$1 colegòu a-a pagina $2",
+       "linksearch-error": "I metacarattei poeuan ese usati solo a-o prinçippio de l'indiriçço.",
+       "listusersfrom": "Mostra i utenti a partî da:",
        "listusers-submit": "Fanni vedde",
        "listusers-noresult": "Utente non trovöo.",
+       "listusers-blocked": "(bloccou)",
+       "activeusers": "Lista di utenti attivi",
+       "activeusers-intro": "Questo o l'è un elenco di utenti ch'han avuo quarche tipo d'attivitæ da $1 {{PLURAL:$1|giorno|giorni}} a questa parte.",
+       "activeusers-count": "$1 {{PLURAL:$1|açione|açioin}} {{PLURAL:$3|inte l'urtimo giorno|inti urtimi $3 giorni}}",
+       "activeusers-from": "Mostra i utenti a partî da:",
+       "activeusers-hidebots": "Ascondi i bot",
+       "activeusers-hidesysops": "Ascondi i amministratoî",
+       "activeusers-noresult": "Nisciun utente o risponde a-i critei impostæ.",
+       "activeusers-submit": "Mostra utenti attivi",
+       "listgrouprights": "Driti do groppo utente",
+       "listgrouprights-summary": "De seguito l'è elencou i groppi utente definii pe questo scito, co-i so driti d'accesso associæ.\nPorieiva esighe di [[{{MediaWiki:Listgrouprights-helppage}}|urteioî informaçioin]] in scî driti individoali.",
+       "listgrouprights-key": "Legenda:\n* <span class=\"listgrouprights-granted\">Drito assegnou</span>\n* <span class=\"listgrouprights-revoked\">Drito revocou</span>",
+       "listgrouprights-group": "Groppo",
+       "listgrouprights-rights": "Driti",
+       "listgrouprights-helppage": "Help:Driti do groppo",
        "listgrouprights-members": "(Elenco di membri)",
+       "listgrouprights-addgroup": "O poeu azonze {{PLURAL:$2|a-o groppo|a-i groppi}}: $1",
+       "listgrouprights-removegroup": "O poeu rimoeuve {{PLURAL:$2|da-o groppo|da-i groppi}}: $1",
+       "listgrouprights-addgroup-all": "O poeu azonze a tutti i groppi",
+       "listgrouprights-removegroup-all": "O poeu rimoeuve da tutti i groppi",
+       "listgrouprights-addgroup-self": "O poeu azonzise {{PLURAL:$2|a-o groppo|a-i groppi}}: $1",
+       "listgrouprights-removegroup-self": "O poeu rimoeuvise {{PLURAL:$2|da-o groppo|da-i groppi}}: $1",
+       "listgrouprights-addgroup-self-all": "O poeu azonzise a tutti i groppi",
+       "listgrouprights-removegroup-self-all": "O poeu rimoeuvise da tutti i groppi",
+       "listgrouprights-namespaceprotection-header": "Restriçioin pe namespace",
+       "listgrouprights-namespaceprotection-namespace": "Namespace",
+       "listgrouprights-namespaceprotection-restrictedto": "Drito ch'o consente a l'utente de modificâ",
+       "listgrants": "Assegnaçioin",
+       "listgrants-summary": "De seguito l'è riportou un elenco de concescioin, co-i so driti utente associæ. I utenti poeuan aotorizzâ e appricaçioin a doeuviâ a proppia utença, ma con di aotorizzaçioin limitæ in base a-e assegnaçioin che l'utente o l'ha dæto a l'appricaçion. Tuttavia, un'appricaçion ch'a l'agisce pe conto de 'n utente a no poeu effettivamente doeuviâ i driti di quæ l'utente o no dispon-e.\nGhe poriæ ese di [[{{MediaWiki:Listgrouprights-helppage}}|urteioî informaçioin]] in scî driti individoali.",
+       "listgrants-grant": "Assegnaçion",
+       "listgrants-rights": "Driti",
+       "trackingcategories": "Categorie de monitoraggio",
+       "trackingcategories-summary": "Questa pagina a l'elenca e categorie de monitoraggio che vegnan popolæ aotomaticamente da-o software MediaWiki. I so nommi poeuan ese cangiæ modificando i relativi messaggi de scistema into namespace {{ns:8}}.",
+       "trackingcategories-msg": "Categoria de monitoraggio",
+       "trackingcategories-name": "Nomme do messaggio",
+       "trackingcategories-desc": "Critei pe l'incluxon intaa categoria",
+       "restricted-displaytitle-ignored": "Pagine con di tittoli da vixualizzâ ignoræ",
+       "restricted-displaytitle-ignored-desc": "A pagina a g'ha un <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> ignorou perché a no l'è equivalente a l'effettivo tittolo da pagina.",
+       "noindex-category-desc": "A pagina a no l'è indiçizzâ da-i robot perché a conten a paola magica <code><nowiki>__NOINDEX__</nowiki></code> e a s'atroeuva inte 'n namespace donde tâ flag a l'è consentia.",
+       "index-category-desc": "A pagina a conten <code><nowiki>__INDEX__</nowiki></code> (e a s'atroeuva inte 'n namespace donde tâ flag a l'è consentia) e quindi a l'è indiçizâ da-i robot, sci ben che normalmente a no-o saieiva.",
+       "post-expand-template-inclusion-category-desc": "A dimenscion da pagina a saiâ ciù grande de <code>$wgMaxArticleSize</code> doppo avei espanso tutti i template, e coscì çerti template no son stæti espansci.",
+       "post-expand-template-argument-category-desc": "A pagina a saiâ ciù grande de <code>$wgMaxArticleSize</code> doppo aver espanso o parametro de un template (quarcosa tra træ parentexi graffe, comme <code>{{{Foo}}}</code>).",
+       "expensive-parserfunction-category-desc": "A pagina a l'adoeuvia troppe fonçioin parser (come <code>#ifexist</code>). Amia [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
+       "broken-file-category-desc": "A pagina a conten un collegamento interotto a un file (un collegamento pe incorpoâ un file quande questo o no l'existe).",
+       "hidden-category-category-desc": "Questa categoria a conten <code><nowiki>__HIDDENCAT__</nowiki></code> inta so pagina, o quæ o l'impedisce ch'a segge mostrâ, in moddo predefinio, into riquaddro di collegamenti a-e categorie de pagine.",
+       "trackingcategories-nodesc": "Nisciun-a descriçion disponibbile.",
+       "trackingcategories-disabled": "A categoria a l'è disabilitâ",
+       "mailnologin": "Nisciun adreçço a chi mandâ o messaggio",
+       "mailnologintext": "Pe inviâ di messaggi e-mail a di atri utenti l'è necessaio [[Special:UserLogin|accede a-o scito]] e avei registrou un adreçço vallido inte proppie [[Special:Preferences|preferençe]].",
        "emailuser": "Invia 'na email a st'utente chi",
-       "defemailsubject": "{{SITENAME}} posta elettronega",
+       "emailuser-title-target": "Invia un'email a questo {{GENDER:$1|utente}}",
+       "emailuser-title-notarget": "Invia una email a un utente",
+       "emailpagetext": "Doeuvia o moddulo sottostante pe inviâ un messaggio e-mail a l'{{GENDER:$1|utente}} indicou. L'adreçço speçificou inte [[Special:Preferences|preferençe]] do mittente o l'appariâ into campo \"Da:\" do messaggio pe consentî a-o destinataio de risponde direttamente.",
+       "defemailsubject": "Messaggio da {{SITENAME}} da l'utente \"$1\"",
+       "usermaildisabled": "e-mail utente disabilitâ",
+       "usermaildisabledtext": "No l'è poscibbile inviâ de e-mail a di atri utenti insce questo wiki",
        "noemailtitle": "Nisciûn conto e-mail",
-       "emailfrom": "Da",
-       "emailto": "A",
-       "emailsubject": "Argumento",
-       "emailmessage": "Comunicaçion",
+       "noemailtext": "Questo utente o no l'ha indicou un adreçço e-mail vallido.",
+       "nowikiemailtext": "Questo utente o l'ha scerto de no riçeive messaggi de posta elettronica da-i atri utenti.",
+       "emailnotarget": "Nomme utente do destinataio inexistente o non vallido.",
+       "emailtarget": "Inseisci o nomme utente do destinataio",
+       "emailusername": "Nomme utente",
+       "emailusernamesubmit": "Invia",
+       "email-legend": "Invia un messaggio e-mail a un atro utente de {{SITENAME}}",
+       "emailfrom": "Da:",
+       "emailto": "A:",
+       "emailsubject": "Sogetto:",
+       "emailmessage": "Messaggio:",
        "emailsend": "Spèdi",
        "emailccme": "Mandame unn-a copia do messagio co unn-a lettìa elettronega.",
+       "emailccsubject": "Coppia do messaggio inviou a $1: $2",
        "emailsent": "Lettìa elettronega spèdïa",
        "emailsenttext": "A teua lettìa elettronega a l'è stæta spèdïa.",
+       "emailuserfooter": "Questa email a l'è stæta {{GENDER:$1|inviâ}} da $1 a {{GENDER:$2|$2}} a traverso a fonçion \"{{int:emailuser}}\" insce {{SITENAME}}.",
+       "usermessage-summary": "Messaggio de scistema",
+       "usermessage-editor": "Messaggê de scistema",
        "watchlist": "Sotta osservassion",
        "mywatchlist": "Sotta oservaçion",
        "watchlistfor2": "Pe $1 $2",
+       "nowatchlist": "A lista di öservæ speciali a l'è voeua.",
+       "watchlistanontext": "Pe vixualizzâ e modificâ l'elenco di öservæ l'è necessaio eseguî l'accesso.",
        "watchnologin": "Non ti t'æ entroö",
-       "addedwatchtext": "A paggina \"[[:$1]]\" a l'è stæta azzonta a-a pròpia [[Special:Watchlist|lista in osservaçion]]. De chì in avanti, i cangiamenti fæti a-a paggina e a-a sêu discûxon sajàn missi in lista lì; o tittolo da paggina o sajà scrîo in '''grascietto''' inta paggina di [[Special:RecentChanges|ûrtimi cangiamenti]] coscì ti o veddi megio. Se ti vêu eliminâla da-a lista in osservaçion ciû târdi, sciacca \"no seguî\" inscia barra de d'âto.",
-       "removedwatchtext": "A paggina \"[[:$1]]\" a l'è stæta scassâa da-a têu lista in osservaçion.",
+       "addwatch": "Azonzi a-a lista sotta öservaçion",
+       "addedwatchtext": "\"[[:$1]]\" e a so paggina de discuscion son stæte azonte a-a proppia [[Special:Watchlist|lista di öservæ]].",
+       "addedwatchtext-short": "A pagina \"$1\" a l'è stæata azonta a-a proppia lista di öservæ.",
+       "removewatch": "Rimoeuvi da-i öservæ speciali",
+       "removedwatchtext": "\"[[:$1]]\" e a so paggina de discuscion son stæte rimosse da-a proppia [[Special:Watchlist|lista di öservæ]].",
+       "removedwatchtext-short": "A pagina \"$1\" a l'è stæata rimossa da-a proppia lista di öservæ.",
        "watch": "Metti sotta oservaçion",
        "watchthispage": "Vigilâ 'sta paggina",
        "unwatch": "Leva da sott'oservaçion",
-       "watchlist-details": "A lista d'oservaçión speçiâle a contegne {{PLURAL:$1|ina pàgina (co-a seu pàgina de discusción)|$1 de pàgine (co-e so pàgine de discusción)}}.",
-       "wlshowlast": "Famme vedde e ûrtime $1 ôe $2 giorni",
+       "unwatchthispage": "Smetti de öservâ",
+       "notanarticle": "Questa paggina a no l'è una voxe",
+       "notvisiblerev": "L'urtima revixon a l'è stæta scassâ",
+       "watchlist-details": "A lista di öservæ speciali a conten {{PLURAL:$1|una pagina (e a rispettiva pagina de discuscion)|$1 pagine (e e rispettive pagine de discuscion)}}.",
+       "wlheader-enotif": "A notiffica via email a l'è attiva.",
+       "wlheader-showupdated": "E paggine che son stæte modificæ doppo l'urtima vixita son evidençiæ in '''grascetto'''.",
+       "wlnote": "De sotta {{PLURAL:$1|a l'è elencâ a modifica ciù reçente apportâ|son elencæ e <strong>$1</strong> modifiche ciù reçente apportæ}} {{PLURAL:$2|inte l'urtima oa|inti urtime <strong>$2</strong> oe}}; i dæti son aggiornæ a-e $4 do $3.",
+       "wlshowlast": "Mostra i urtime $1 oe $2 giorni",
+       "watchlist-hide": "Ascondi",
+       "watchlist-submit": "Mostra",
+       "wlshowtime": "Periodo de tempo da vixualizzâ:",
+       "wlshowhideminor": "cangiamenti menoî",
+       "wlshowhidebots": "Bot",
+       "wlshowhideliu": "utenti registræ",
+       "wlshowhideanons": "utenti anonnimi",
+       "wlshowhidepatr": "cangiaménti controllæ",
+       "wlshowhidemine": "e mæ modiffiche",
+       "wlshowhidecategorization": "categorizzaçion da paggina",
        "watchlist-options": "Inpostaçioìn di oservæ speciâli",
        "watching": "Inti osservæ speçiâli...",
        "unwatching": "Scassâ da-i osservæ speçiâli",
+       "watcherrortext": "S'è veificou 'n errô durante a modifica di öservæ pe \"$1\".",
+       "enotif_reset": "Marca tutte-e paggine comme za vixitæ",
+       "enotif_impersonal_salutation": "Utente de {{SITENAME}}",
+       "enotif_subject_deleted": "A paggina $1 de {{SITENAME}} a l'è stæta scassâ da {{gender:$2|$2}}",
+       "enotif_subject_created": "A pagina $1 de {{SITENAME}} a l'è stæta creâ da {{gender:$2|$2}}",
+       "enotif_subject_moved": "A pagina $1 de {{SITENAME}} a l'è stæta mesciâ da {{gender:$2|$2}}",
+       "enotif_subject_restored": "A paggina $1 de {{SITENAME}} a l'è stæta ripristinâ da {{gender:$2|$2}}",
+       "enotif_subject_changed": "A pagina $1 de {{SITENAME}} a l'è stæta modificâ da {{gender:$2|$2}}",
+       "enotif_body_intro_deleted": "A pagina $1 de {{SITENAME}} a l'è stæta scassâ da {{gender:$2|$2}} o $PAGEEDITDATE (amia $3 pe-a verscion attoale).",
+       "enotif_body_intro_created": "A pagina $1 de {{SITENAME}} a l'è stæta creâ da {{gender:$2|$2}} o $PAGEEDITDATE, amia $3 pe-a verscion attoale.",
+       "enotif_body_intro_moved": "A pagina $1 de {{SITENAME}} a l'è stæta mesciâ da {{gender:$2|$2}} o $PAGEEDITDATE, amia $3 pe-a verscion attoale.",
+       "enotif_body_intro_restored": "A pagina $1 de {{SITENAME}} a l'è stæta ripristinâ da {{gender:$2|$2}} o $PAGEEDITDATE, amia $3 pe-a verscion attoale.",
+       "enotif_body_intro_changed": "A pagina $1 de {{SITENAME}} a l'è stæta modificâ da {{gender:$2|$2}} o $PAGEEDITDATE, amia $3 pe-a verscion attoale.",
+       "enotif_lastvisited": "Vixita $1 pe vedde tutte e modiffiche da l'urtima vixita.",
+       "enotif_lastdiff": "Vixita $1 pe vedde a modiffica.",
        "enotif_anon_editor": "ûtente anònnimo $1",
+       "enotif_body": "Gentî $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nÖgetto de l'intervento, inseio da l'aotô: $PAGESUMMARY $PAGEMINOREDIT\n\nContatta l'aotô:\nvia posta eletronnica: $PAGEEDITOR_EMAIL\nin sciô scito: $PAGEEDITOR_WIKI\n\nNo saiâ mandou atre notiffiche in caxo de urteioî attivitæ, se no ti vixiti a pagina doppo avei effettuou l'accesso. Inoltre, l'è poscibbile modificâ e impostaçioin de notiffica pe tutte e paggine inta lista dei öservæ speciali.\n\nO scistema de notiffica de {{SITENAME}}, a-o to serviççio\n\n--\nPe modificâ e impostaçioin de notiffiche via posta elettronnica, vixita \n{{canonicalurl:{{#special:Preferences}}}}\n\nPe modificâ a lista di öservæ speciali, vixita \n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPe rimoeuve a pagina da-a lista di öservæ speciali, vixita\n$UNWATCHURL\n\nPe commentâ e riçeive agiutto:\n$HELPPAGE",
        "changed": "cangiâ",
        "deletepage": "Scassa a paggina",
+       "confirm": "Conferma",
+       "excontent": "o contegnuo o l'ea: '$1'",
+       "excontentauthor": "o contegnuo o l'ea: '$1', e l'unnico contributô o l'ea \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|msg]])",
+       "exbeforeblank": "O contegnuo primma do svoeuamento o l'ea: '$1'",
        "delete-confirm": "Scassa \"$1\"",
        "delete-legend": "Scassa",
-       "historywarning": "Attension: A paggina c'a se sta pe scassâ a g'ha 'na cronologîa:",
+       "historywarning": "'''Attençion:''' a paggina che ti stæ pe scassâ a g'ha una cronologia con $1 {{PLURAL:$1|verscion|verscioin}}:",
+       "historyaction-submit": "Mostra",
        "confirmdeletetext": "Ti stæ pe scassâ pe sempre da-o database 'na paggina ò 'n'immaggine, assemme a tûtta a sêu cronologîa. Pe cortexia, conferma che davvei ti vêu andâ avanti con quella cancellassion, che ti capisci perfettamente e conseguense de 'st'assion e che a s'adatta a-e linnie guidda stabilîe in [[{{MediaWiki:Policy-url}}]].",
        "actioncomplete": "Açion completâ",
        "actionfailed": "Açión falîa",
        "deletedtext": "A paggina \"$1\" a l'è stæta scassâ. Consultâ o $2 pe 'na lista de paggine scassæ de reçente.",
        "dellogpage": "Registro de cose scassæ",
+       "dellogpagetext": "De sotta gh'è 'na lista co-e paggine scassæ ciu de reçente.",
+       "deletionlog": "registro de scassatue",
+       "reverted": "Ripristinou a verscion precedente",
        "deletecomment": "Raxon:",
        "deleteotherreason": "Ûn âtro motivo",
        "deletereasonotherlist": "Ûnn'âtra raxon",
+       "deletereason-dropdown": "* Motivaçioin ciù comun-e pe-a scançellaçion\n** Spam\n** Vandalismo\n** Violaçion do drito d'aotô\n** Recesta de l'aotô\n** Redirect rotto",
+       "delete-edit-reasonlist": "Modiffica e raxoin do scassamento",
+       "delete-toobig": "A cronologia de questa pagina a l'è ben longa (oltre $1 {{PLURAL:$1|verscion|verscioin}}). A so scançellaçion a l'è stæta limitâ pe evitâ de creâ açidentalmente di problemi de fonçionamento a-o database de {{SITENAME}}.",
+       "delete-warning-toobig": "A cronologia de questa pagina a l'è ben longa (oltre $1 {{PLURAL:$1|verscion|verscioin}}). A so scançellaçion a poeu creâ di problemi de fonçionamento a-o database do {{SITENAME}}; procede con caotella.",
+       "deleteprotected": "No ti poeu scassâ questa paggina perché a l'è stæta protetta.",
+       "deleting-backlinks-warning": "<strong>Attençion:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|di atre pagine]] contengnan di collegamenti o de incluxoin a-a paggina che t'ê aproeuvo a scassâ.",
+       "rollback": "Annulla e modiffiche",
        "rollbacklink": "rollback",
        "rollbacklinkcount": "rollback de {{PLURAL:$1|una modiffica|$1 modiffiche}}",
+       "rollbacklinkcount-morethan": "rollback de ciù de {{PLURAL:$1|una modiffica|$1 modiffiche}}",
+       "rollbackfailed": "Rollback fallio",
+       "rollback-missingparam": "Parammetri obrigatoi mancanti inta recesta.",
        "cantrollback": "No se peu tornâ inderê; l'utente ch'o l'ha fæto quelle modiffiche o l'è stæto l'unico contribuente.",
-       "alreadyrolled": "O no se peû tornâ inderê a-i ûrtimi cangiamenti da pagina [[:$1]]\nda [[User:$2|$2]] ([[User talk:$2|Ciæti]]); quarche âtro\no l'à cangiâ ò o l'è zà tornòu inderê.\nL'ûrtimo cangiamento o ghe l'à fæto [[User:$3|$3]] ([[User talk:$3|Ciæti]]).",
-       "revertpage": "E modificaçioin de [[Special:Contributions/$2|$2]] ([[User talk:$2|Ciæti]]) son stæte eliminæ; riportæ a verscion de primma de [[User:$1|$1]]",
+       "alreadyrolled": "No l'è poscibbile annullâ e modiffiche apportæ a-a pagina [[:$1]] da parte de [[User:$2|$2]] ([[User talk:$2|discuscion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); un atro utente o l'ha zà modificou a pagina oppù o l'ha effettuou o rollback.\n\nA modifica ciù reçente a.a paggina a l'è stæta apportâ da [[User:$3|$3]] ([[User talk:$3|discuscion]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
+       "editcomment": "L'ogetto da modiffica o l'ea: <em>$1</em>.",
+       "revertpage": "Annullou e modiffiche de [[Special:Contributions/$2|$2]] ([[User talk:$2|discuscion]]), riportâ a-a verscion precedente de [[User:$1|$1]]",
+       "revertpage-nouser": "Annullou e modiffiche de un utente ascoso, riportâ a-a verscion precedente de {{GENDER:$1|[[User:$1|$1]]}}",
+       "rollback-success": "Annullou e modiffiche de $1; paggina riportâ a l'urtima verscion de $2.",
+       "rollback-success-notify": "Annullou e modiffiche de $1;\npaggina riportâ a l'urtima revixon de $2. [$3 Mostra e modiffiche]",
+       "sessionfailure-title": "Sescion fallia",
+       "sessionfailure": "S'è veificou un problema inta sescion ch'a l'identiffica l'accesso; o scistema o no l'ha eseguio o comando impartio pe precauçion. Torna a-a paggina precedente co-o tasto 'Inderê' do to browser, recarega a paggina e riproeuva.",
+       "changecontentmodel": "Cangia o modello de contegnuo de 'na paggina",
+       "changecontentmodel-legend": "Cangia o modello de contegnuo",
+       "changecontentmodel-title-label": "Tittolo da paggina",
+       "changecontentmodel-model-label": "Noeuvo modello de contegnuo",
+       "changecontentmodel-reason-label": "Raxon:",
+       "changecontentmodel-submit": "Cangia",
+       "changecontentmodel-success-title": "O modello de contegnuo o l'è stæto modificou",
+       "changecontentmodel-success-text": "O tipo de contegnuo de [[:$1]] o l'è stæto modificou.",
+       "changecontentmodel-cannot-convert": "O contegnuo de [[:$1]] o no poeu ese convertio inte 'n tipo de $2.",
+       "changecontentmodel-nodirectediting": "O modello de contegnuo $1 o no supporta a modiffica diretta",
+       "changecontentmodel-emptymodels-title": "Nisciun modello de contegnuo disponibbile",
+       "changecontentmodel-emptymodels-text": "O contegnuo de [[:$1]] o no poeu ese convertio inte nisciun tipo.",
+       "log-name-contentmodel": "Modiffiche do modello di contegnui",
+       "log-description-contentmodel": "Eventi relativi a-o modello de contegnuo de 'na paggina",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|l'ha creou}} a paggina $3 doeuviando un modello de contegnuo non predefinio \"$5\"",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|l'ha modificou}} o modello de contegnuo da paggina $3 da \"$4\" a \"$5\"",
+       "logentry-contentmodel-change-revertlink": "ripristina",
+       "logentry-contentmodel-change-revert": "ripristina",
        "protectlogpage": "Protessioin",
+       "protectlogtext": "De sotta gh'è 'na lista di cangi a-e proteçioin de paggine.\nAmia a [[Special:ProtectedPages|lista de pagine protette]] pe l'elenco de proteçioin de pagina attoalmente attive.",
        "protectedarticle": "o l'à protetto \"[[$1]]\"",
+       "modifiedarticleprotection": "ha modificou o livello de proteçion de \"[[$1]]\"",
+       "unprotectedarticle": "o l'ha sprotezuo \"[[$1]]\"",
+       "movedarticleprotection": "o l'ha mesciou a proteçion da \"[[$2]]\" a \"[[$1]]\"",
+       "protect-title": "Cangio do livello de proteçion pe \"$1\"",
+       "protect-title-notallowed": "Veddi o livello de proteçion de \" $1 \"",
        "prot_1movedto2": "[[$1]] mesciòu a [[$2]]",
+       "protect-badnamespace-title": "Namespace non protezibbile",
+       "protect-badnamespace-text": "E pagine de questo namespace no poeuan ese protezue.",
+       "protect-norestrictiontypes-text": "Questa pagina a no poeu ese protetta perché non gh'è arcun tipo de restriçion disponibbile.",
+       "protect-norestrictiontypes-title": "Paggina non protezibbile",
        "protect-legend": "Confermâ protession",
        "protectcomment": "Raxon:",
        "protectexpiry": "Scadensa:",
        "protect_expiry_invalid": "Scadensa invalida.",
        "protect_expiry_old": "Dæta de scadensa into passòu.",
+       "protect-unchain-permissions": "Desblocca di urteioî opçioin de proteçion",
        "protect-text": "Chì o l'è poscibbile vedde e modificâ o livello de protession pe-a paggina '''$1'''.",
+       "protect-locked-blocked": "No ti poeu cangiâ i livelli de proteçion quande gh'è un blocco. E impostaçioin corrente pe-a pagina son '''$1''':",
+       "protect-locked-dblock": "Imposcibile modificâ i livelli de proteçion durante un blocco do database.\nE impostaçioin corrente pe-a paggina son '''$1''':",
        "protect-locked-access": "No ti g'hæ permisso pe modificâ i livelli de protession da paggina.\nQueste son e impostassioîn correnti pe 'sta paggina ('''$1'''):",
-       "protect-cascadeon": "Pe-o momento 'sta paggina chì a l'è bloccâa perché a l'è inclûsa {{PLURAL:$1|inta paggina indicâa apprêuvo, pe-a quæ|inte paggine indicæ apprêuvo, pe-e quæ}} a l'è attiva a protession recorsciva. O se pêu modificâ o livello de protession individuâle da paggina, ma l'impostassioîn derivanti da-a protession recorsciva no sajàn modificæ.",
-       "protect-default": "(predefinîo)",
-       "protect-fallback": "Besêugna avei permisso \"$1\"",
-       "protect-level-autoconfirmed": "Solo ûtenti registræ",
-       "protect-level-sysop": "Solo amministratoî",
+       "protect-cascadeon": "A-o momento questa pagina a l'è bloccâ perché inclusa {{PLURAL:$1|inta pagina indicâ de seguito, pe-a quæ|inte pagine indicæ de seguito, pe-e quæ}} l'è attiva a proteçion ricorsciva.\nE modifiche a-o livello de proteçion individoale da pagina, no avian effetto in sce-e impostaçioin derivante da-a proteçion ricorsciva.",
+       "protect-default": "Aotorizza tutti i utenti",
+       "protect-fallback": "Consentio solo a-i utenti con permisso \"$1\"",
+       "protect-level-autoconfirmed": "Consentio solo a-i utenti aotoconvalidæ",
+       "protect-level-sysop": "Consentio solo a-i amministratoî",
        "protect-summary-cascade": "recorsciva",
        "protect-expiring": "scadensa: $1 (UTC)",
+       "protect-expiring-local": "o descazze o $1",
+       "protect-expiry-indefinite": "indefinio",
        "protect-cascade": "Protession recorsciva (estende a protession a tûtte e paggine inclûse in questa chì).",
        "protect-cantedit": "Ti no ti pêu modificâ i livelli de protession pe-a paggina se no ti g'hæ i permissi pe modificâ a paggina mæxima.",
-       "protect-expiry-options": "2 ôe:2 hours,1 giorno:1 day,3 giorni:3 days,1 settemann-a:1 week,2 settemann-e:2 weeks,1 meise:1 month,3 meixi:3 months,6 meixi:6 months,1 anno:1 year,infinîo:infinite",
+       "protect-othertime": "Duata non in elenco:",
+       "protect-othertime-op": "duata non in elenco",
+       "protect-existing-expiry": "Scadença attoale: $2, $3",
+       "protect-existing-expiry-infinity": "Scadença attoale: infinio",
+       "protect-otherreason": "Atri motivi/detaggi:",
+       "protect-otherreason-op": "Un'atra raxon",
+       "protect-dropdown": "*Motivi comun de proteçion\n** Reiteræ vandalismi\n** Reiteræ inseimenti de spam\n** Guæra de modiffiche contra-produxente\n** Paggina con ato traffego",
+       "protect-edit-reasonlist": "Modiffica e raxoin pe-a proteçion",
+       "protect-expiry-options": "1 oa:1 hour,1 giorno:1 day,1 setteman-a:1 week,2 setteman-e:2 weeks,1 meise:1 month,3 meixi:3 months,6 meixi:6 months,1 anno:1 year,infinio:infinite",
        "restriction-type": "Permisso",
        "restriction-level": "Livello de restrission",
+       "minimum-size": "Dimenscion minnima",
+       "maximum-size": "Dimenscion mascima:",
+       "pagesize": "(byte)",
        "restriction-edit": "Cangia",
        "restriction-move": "Mescia",
+       "restriction-create": "Crea",
+       "restriction-upload": "Carrega",
+       "restriction-level-sysop": "protetta",
+       "restriction-level-autoconfirmed": "semi-protezua",
        "restriction-level-all": "Tutti i livelli",
        "undelete": "Amîa e paggine scassæ",
+       "undeletepage": "Veddi e recuppera e pagine scançellæ",
+       "undeletepagetitle": "'''Quanto segue o l'è composto da de revixoin scassæ de [[:$1|$1]]'''.",
+       "viewdeletedpage": "Veddi e paggine scassæ",
+       "undeletepagetext": "{{PLURAL:$1|A seguente pagina a l'è stæta scassâ, ma a l'è ancon in archivio e pertanto a poeu ese recuperâ|Le seguente pagine son stæte scassæ, ma son ancon in archivio e pertanto poeuan ese recuperæ}}. L'archivio o poeu ese vuou periodicamente.",
+       "undelete-fieldset-title": "Ripristina revixoin",
+       "undeleteextrahelp": "Pe recuperâ l'intrega cronologia da pagina, lascia tutte e caselle deseleçionæ e fanni clic insce '''''{{int:undeletebtn}}'''''.\nPe effettuâ un ripristino selettivo, seleçion-a e caselle corrispondente a-e verscioin da ripristinâ e fanni clic insce '''''{{int:undeletebtn}}'''''.",
+       "undeleterevisions": "{{PLURAL:$1|Una revixon scassâ|$1 revixoin scassæ}}",
+       "undeletehistory": "Recuperando questa pagina, tutte e so verscioin saian ripristinæ inta relativa cronologia.\nSe doppo la scançellaçione l'è stato creou una noeuva pagina co-o mæximo tittolo, e verscioin recuperæ saian inseie inta cronologia precedente.",
+       "undeleterevdel": "O ripristino o no saiâ effettuou s'o determina a scançellaçion parçiâ da verscion attoale da pagina o do file interessou. In tâ caxo, l'è necessaio smarcâ o levâ l'oscuramento da-e verscioin scassæ ciù reçenti.",
+       "undeletehistorynoadmin": "Questa pagina a l'è stæta scassâ.\nO motivo da scassatua o l'è mostrou chì sotta, insemme a-i detaggi de l'utente ch'o l'ha modificou questa pagina primma da scassatua.\nO testo contegnuo inte verscioin scassæ o l'è disponibile solo a-i amministratoî.",
+       "undelete-revision": "Verscion scassâ da pagina $1, inseia o $4 a $5 da $3:",
+       "undeleterevision-missing": "Verscion errâ o mancante. O collegamento o l'è errou o dunque a verscion a l'è stæta zà ripristinâ ò eliminâ da l'archivvio.",
+       "undelete-nodiff": "No l'è stæto trovou nisciun-a verscion precedente.",
        "undeletebtn": "Ristorâ",
        "undeletelink": "fanni védde/repìggia",
        "undeleteviewlink": "fanni védde",
-       "cannotundelete": "O repiggio de i dæti o non l'è riuscïo (i peun ese za stæti repiggiæ da quarchedun ätro).",
+       "undeleteinvert": "Inverti a seleçion",
+       "undeletecomment": "Raxon:",
+       "undeletedrevisions": "{{PLURAL:$1|Una verscion recuperâ|$1 verscioin recuperæ}}",
+       "undeletedrevisions-files": "{{PLURAL:$1|Una verscion|$1 verscioin}} e $2 file recuperæ",
+       "undeletedfiles": "{{PLURAL:$1|Un file recuperou|$1 file recuperæ}}",
+       "cannotundelete": "Ripristino non riuscio:\n$1",
+       "undeletedpage": "'''A pagina $1 a l'è stæta recuperâ'''\n\nConsurta o [[Special:Log/delete|registro de scançellaçioin]] pe vedde e scançellaçioin e i recupperi ciù reçente.",
+       "undelete-header": "Consurta o [[Special:Log/delete|registro de scançellaçioin]] pe vedde e scassatue ciù reçente.",
+       "undelete-search-title": "Çerca inte pagine scassæ",
+       "undelete-search-box": "Çerca e paggine scassæ",
+       "undelete-search-prefix": "Mostra e paggine che començan con:",
+       "undelete-search-submit": "Çerca",
+       "undelete-no-results": "Nisciun-a pagina corrispondente inte l'archivio de scançellaçioin.",
+       "undelete-filename-mismatch": "Imposcibbile annullâ a scançellaçion da verscion do file con timestamp $1: nomme do file non corrispondente.",
        "undelete-bad-store-key": "No se peu repiggiâ o file co-a dæta $1: o file o no gh'ea za ciu primma d'ese scassou.",
        "undelete-cleanup-error": "Errô into scassâ o file d'archivio non utilizzòu \"$1\".",
+       "undelete-missing-filearchive": "Imposcibile ripristinâ l'ID $1 de l'archivio file in quanto o no l'è presente into database. O poriæ ese stæto za ripristinou.",
+       "undelete-error": "Errô into ripristino da pagina",
        "undelete-error-short": "Errô repiggiando i dæti do file \"$1\".",
        "undelete-error-long": "Gh'è stæto di erroî inte l'annullâ a cançellaçion do file:\n\n$1",
+       "undelete-show-file-confirm": "T'ê seguo de voei amiâ a verscion scassâ do file \"<nowiki>$1</nowiki>\" do $2 a $3?",
+       "undelete-show-file-submit": "Sci",
        "namespace": "Namespace:",
        "invert": "Invertî a seleçión",
        "tooltip-invert": "Selession-a sta casella pe asconde e modiffiche a-e paggine a l'interno do namespace selessionou (e o namespace associou, se selessionou)",
+       "tooltip-whatlinkshere-invert": "Marca sta casella pe asconde i collegamenti da-e pagine a l'interno do namespace seleçionou",
        "namespace_association": "Namespace associou",
        "tooltip-namespace_association": "Selession-a sta casella pe includde ascì a paggina de discuscion ò l'oggetto do namespace associou co-o namespace selessionou",
        "blanknamespace": "(Prinçipâ)",
        "contributions-title": "Contribuçioìn de $1",
        "mycontris": "Contribuçioin",
        "anoncontribs": "Contribuçioin",
-       "contribsub2": "Pe $1 ($2)",
-       "uctop": "(ûrtima pe-a paggina)",
+       "contribsub2": "Pe {{GENDER:$3|$1}} ($2)",
+       "contributions-userdoesnotexist": "L'utença \"$1\" a no l'è registrâ.",
+       "nocontribs": "Cangi che soddisfan i critei de riçerca no se n'è atrovou.",
+       "uctop": "(attoale)",
        "month": "Partindo da-o meize (e precedénti):",
        "year": "Partindo da l'anno (e precedenti):",
        "sp-contributions-newbies": "Fanni védde sôlo e contribuçioìn di nêuvi utenti",
        "sp-contributions-newbies-sub": "Pe i nêuvi ûtenti",
+       "sp-contributions-newbies-title": "Contribuçioin di noeuvi utenti",
        "sp-contributions-blocklog": "Blòcchi",
+       "sp-contributions-suppresslog": "contributi utente soppresci",
+       "sp-contributions-deleted": "contributi utente scassæ",
        "sp-contributions-uploads": "caregaménti",
        "sp-contributions-logs": "log",
        "sp-contributions-talk": "Ciæti",
+       "sp-contributions-userrights": "manezzo di driti di utenti",
+       "sp-contributions-blocked-notice": "St'utente o l'è attualmente bloccòu.\nL'urtimo elemento into registro di blocchi o l'è riportòu chì de sotta pe rifeimento:",
+       "sp-contributions-blocked-notice-anon": "St'addreçço IP o l'è attoalmente bloccòu.\nL'urtimo elemento into registro di blocchi o l'è riportòu chì de sotta pe rifeimento:",
        "sp-contributions-search": "Riçerca contribuçioìn",
        "sp-contributions-username": "Indirìsso IP ò nómme utente:",
        "sp-contributions-toponly": "Fanni védde sôlo i cangiaménti ch'en i ùrtime revixoìn da pàgina",
+       "sp-contributions-newonly": "Fanni védde sôlo i cangiaménti ch'en de creaçioin de pàgina",
+       "sp-contributions-hideminor": "Ascondi e modifiche menoî",
        "sp-contributions-submit": "Çerca",
        "whatlinkshere": "Cöse se colega chì",
        "whatlinkshere-title": "Pàgine c'apontàn a $1",
        "whatlinkshere-page": "Pàgina:",
        "linkshere": "E pàgine segoenti apontan a '''[[:$1]]''':",
        "nolinkshere": "Nisciùnn-a pàgina a se collega con '''[[:$1]]'''.",
+       "nolinkshere-ns": "Pagine ch'apontan a '''[[:$1]]''' into namespace seleçionou no ghe n'è.",
        "isredirect": "Paggina de rindirissamento",
        "istemplate": "Incluxon",
        "isimage": "Colegamento a file",
        "whatlinkshere-next": "{{PLURAL:$1|sûccescivo|sûccescivi $1}}",
        "whatlinkshere-links": "← colegaménti",
        "whatlinkshere-hideredirs": "$1 i rendirissamenti",
-       "whatlinkshere-hidetrans": "$1 Incluxon",
+       "whatlinkshere-hidetrans": "$1 Incluxoin",
        "whatlinkshere-hidelinks": "$1 colegaménti",
-       "whatlinkshere-hideimages": "$1 colegaménti di file",
+       "whatlinkshere-hideimages": "$1 colegamenti da file",
        "whatlinkshere-filters": "Filtri",
-       "blockip": "Blocca l'ûtente",
+       "whatlinkshere-submit": "Vanni",
+       "autoblockid": "Aotobrocco #$1",
+       "block": "Blocca utente",
+       "unblock": "Desblocca utente",
+       "blockip": "Blocca {{GENDER:$1|utente}}",
+       "blockip-legend": "Blocca l'utente",
+       "blockiptext": "Doeuvia o moddulo sottostante pe bloccâ l'accesso in scrittua a un speciffico addreçço IP ò a un utente registrou.\nO blocco o dev'ese doeuviou pe prevegnî di atti de vandalismo e in streita öservança de [[{{MediaWiki:Policy-url}}|reggole de {{SITENAME}}]].\nIndica o motivo speçiffico pe-o quæ se procede a-o blocco (presempio, çitando i tittoli di eventuæ paggine ögetto de vandalismo).\nTi poeu bloccâ di ntervalli de IP doeuviando a scintasci [https://it.wikipedia.org/wiki/CIDR CIDR]; l'intervallo ciù ampio consentio o l'è /$1 pe IPv4 e /$2 pe IPv6.",
+       "ipaddressorusername": "Adreçço IP ò nómme utente:",
+       "ipbexpiry": "Scadença:",
        "ipbreason": "Raxon:",
+       "ipbreason-dropdown": "*Motivaçioni ciù comun-e pe-i blocchi\n** Inseimento de informaçioin fase\n** Rimoçion di contegnti da-e paggine\n** Collegamenti promoçionæ a di sciti esterni\n** Inseimento di contegnui privi de senso\n** Comportamenti intimidatoi ò molestie\n** Uso indebbito de utençe murtiple\n** Nomme utente inaçettabbile",
+       "ipb-hardblock": "Impedisci a-i utenti registræ de contribuî da questo adreçço IP",
+       "ipbcreateaccount": "Impedisci a registraçion",
+       "ipbemailban": "Impedisci a l'utente l'invio di email",
+       "ipbenableautoblock": "Blocca aotomaticamente l'urtimo adreçço IP doeuviou da l'utente e i succescivi da-i quæ tentan e modiffiche",
+       "ipbsubmit": "Blocca st'utente",
+       "ipbother": "Duata non in elenco:",
        "ipboptions": "2 ôe:2 hours,1 giorno:1 day,3 giorni:3 days,1 settemann-a:1 week,2 settemann-e:2 weeks,1 meise:1 month,3 meixi:3 months,6 meixi:6 months,1 anno:1 year,infinîo:infinite",
+       "ipbhidename": "Ascondi o nomme utente da-e modiffiche e da-i elenchi.",
+       "ipbwatchuser": "Controlla e pagine e-e discuscioin utente de questo utente",
+       "ipb-disableusertalk": "Impedisci a questo utente de modificâ a proppia paggina de discuscion dementre ch'o l'è bloccou",
+       "ipb-change-block": "Re-blocca l'utente con queste impostaçioin",
+       "ipb-confirm": "Conferma o blocco",
        "badipaddress": "Indirisso IP non valido",
        "blockipsuccesssub": "Blocco ariêscîo",
-       "blockipsuccesstext": "[[Special:Contributions/$1|$1]] o l'è stæto bloccou.\n<br />Veddi [[Special:BlockList|Lista di addressi IP bloccæ]] pe vedde i blocchi attivi.",
+       "blockipsuccesstext": "[[Special:Contributions/$1|$1]] o l'è stæto bloccou.\n<br />Amia a [[Special:BlockList|lista di adreççi IP bloccæ]] pe vedde i blocchi attivi.",
+       "ipb-blockingself": "Ti stæ pe bloccâ ti mæximo! T'ê seguo die voeilo fâ?",
+       "ipb-confirmhideuser": "Ti stæ pe bloccâ un utente con l'opçion \"Ascondi utente\" abilitâ.\nDe sta mainea o nomme utente o saiâ sopresso da tutte le liste e-e voxe de registro.\nT'ê seguo de voeilo fâ?",
+       "ipb-confirmaction": "Se t'ê seguo de voeilo fâ davei, controlla o campo \"{{int:ipb-confirm}}\" in fondo.",
+       "ipb-edit-dropdown": "Modifica i motivi do blocco",
+       "ipb-unblock-addr": "Sblocca $1",
+       "ipb-unblock": "Sblocca un utente ò un adreçço IP",
+       "ipb-blocklist": "Elenca i blocchi attivi",
+       "ipb-blocklist-contribs": "Contribuçioin de {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "$1 arestæ",
+       "unblockip": "Desblocca utente",
+       "unblockiptext": "Doeuvia o moddulo sottostante pe restituî l'accesso in scrittua a 'n utente ò adreçço IP bloccou.",
+       "ipusubmit": "Leva sto blocco",
+       "unblocked": "L'utente [[User:$1|$1]] o l'è stæto sbloccou",
+       "unblocked-range": "$1 o l'è stæto sbloccou",
+       "unblocked-id": "O blocco $1 o l'è stæto rimòsso",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] o l'è stæto sbloccou.",
+       "blocklist": "Utenti bloccæ",
        "ipblocklist": "Utenti blocæ",
+       "ipblocklist-legend": "Çerca un utente bloccou",
+       "blocklist-userblocks": "Ascondi i blocchi di utenti registræ",
+       "blocklist-tempblocks": "Ascondi i blocchi temporannei",
+       "blocklist-addressblocks": "Ascondi i blocchi de un solo IP",
+       "blocklist-rangeblocks": "Ascondi i blocchi de range",
+       "blocklist-timestamp": "Dæta e oa",
+       "blocklist-target": "Destinaçion",
+       "blocklist-expiry": "O descazze",
+       "blocklist-by": "Amministratô ch'o l'ha misso o blocco",
+       "blocklist-params": "Parammetri de blocco",
+       "blocklist-reason": "Raxon",
+       "ipblocklist-submit": "Çerca",
+       "ipblocklist-localblock": "Blocco locale",
+       "ipblocklist-otherblocks": "{{PLURAL:$1|Atro blocco|Atri blocchi}}",
+       "infiniteblock": "infinio",
+       "expiringblock": "o descazze o $1 a $2",
        "anononlyblock": "Solo anonnimi",
+       "noautoblockblock": "blocco aotomatico disabilitou",
+       "createaccountblock": "registraçion bloccâ",
        "emailblock": "posta elettronega bloccâ",
+       "blocklist-nousertalk": "o no poeu modificâ a proppia pagina de discuscion",
        "ipblocklist-empty": "A lista di blocchi a l'è veua.",
+       "ipblocklist-no-results": "L'adreçço IP ô o nomme utente domandou o no l'è bloccou.",
        "blocklink": "Blocca",
        "unblocklink": "sblòcca",
        "change-blocklink": "càngia blòcco",
        "contribslink": "Contribuçioìn",
-       "autoblocker": "Affermoö automaticamente perchè o teu indirisso IP o l'è stæto usöo da \"[[User:$1|$1]]\" neuvamente. A razon dæta pe affermâ $1 a l'è stæta:\n\"$2\"",
+       "emaillink": "manda e-mail",
+       "autoblocker": "Bloccou aotomaticamente perché l'adreçço IP o l'è condiviso con l'utente \"[[User:$1|$1]]\".\nO blocco de l'utente $1 o l'è stæto imposto pe-o seguente motivo: \"$2\".",
        "blocklogpage": "Blòcchi",
+       "blocklog-showlog": "Questo utente o l'è stæto bloccou in precedença. O registro di blocchi o l'è riportou de sotta pe rifeimento:",
+       "blocklog-showsuppresslog": "Questo utente o l'è stæto bloccou e nscoso in precedença. O registro de rimoçioin o l'è riportou de sotta pe rifeimento:",
        "blocklogentry": "blocòu [[$1]] pe in periodo de $2 $3",
-       "blocklogtext": "Sta chie a l'è unn-a lista de affermaçioin fæte e levæ.\nI indirissi IP affermæ automaticamente non son  consideræ.\nVeddi a [[Special:BlockList|Lista de i indirissi IP affermæ]] pe e informaçioin neuve.",
+       "reblock-logentry": "o l'ha cangiou e impostaçioin do blocco pe [[$1]] co-ina scadença de $2 $3",
+       "blocklogtext": "De sotta gh'è 'n registro di açioin de blocco e sblocco utenti.\nI adreççi IP bloccæ aotomaticamente no son elencæ.\nConsurta l'[[Special:BlockList|elenco di blocchi]] pe l'elenco di bandi o blocchi attoalmente opiativi.",
+       "unblocklogentry": "o l'ha sbloccou $1",
        "block-log-flags-anononly": "Utenti anonimmi soö",
        "block-log-flags-nocreate": "Neuve registrascioin non son permisse",
        "block-log-flags-noautoblock": "O blocco automatego o non l'è attïvo",
        "block-log-flags-noemail": "A posta elettronega a non l'è attïva",
+       "block-log-flags-nousertalk": "o no poeu modificâ a proppia pagina de discuscion",
+       "block-log-flags-angry-autoblock": "blocco aotomatico avançou attivo",
+       "block-log-flags-hiddenname": "nomme utente ascoso",
+       "range_block_disabled": "O drito d'aministratô de bloccâ di intervalli d'adreççi IP o l'è disabilitou.",
+       "ipb_expiry_invalid": "Scadença non vallida.",
+       "ipb_expiry_old": "Scadença za trascorsa.",
+       "ipb_expiry_temp": "I blocchi di nommi utenti ascoxi devan ese permanenti.",
        "databasenotlocked": "O database o no l'è bloccòu.",
        "move-page-legend": "Mescia a paggina",
        "movepagetext": "Chì o se pêu dâ 'n nêuvo nomme a 'na paggina, stramûando tûtta a sêu cronologîa a-o nêuvo nomme.\nA paggina attuâle a fa outomaticamente 'n rindirissamento a-o nêuvo tittolo.\nI collegamenti escistenti no sajàn aggiornæ; veriffica che 'sto stramûo o no l'agge creòu doggi rindirissamenti ò rindirissamenti sballiæ.\nA responsabilitæ pe tegnî i collegamenti sempre donde deivan andâ a l'è têu.\n\nA paggina a '''no''' sajà stramûâa se ghe foisse zà ûnn-a co-o nêuvo nomme, a meno c'a no segge vêua ò fæta solo da 'n rindirissamento a-a vegia e a no l'agge verscioîn preçedenti.\nIn caso de stramûo sballiòu o se pêu tornâ sûbbito a-o vegio tittolo, e o no l'è poscibbile sorvescrive pe errô 'na paggina zà escistente.\n\n'''ATTENSION:'''\n'N cangiamento coscì grande o porieiva creâ di controtempi e problemmi, sorvetûtto pe-e paggine ciû viscitæ.\nPensa ben e conseguense de 'sto stramûo primma d'andâ avanti!",
        "thumbnail_error": "Errô inta creassion da miniatûa: $1",
        "thumbnail_invalid_params": "Parametri da a imàginetta non validi",
        "importlogpage": "Importassioîn",
-       "tooltip-pt-userpage": "A teu pagina utilizatô",
-       "tooltip-pt-mytalk": "E mæ discûscioîn",
-       "tooltip-pt-preferences": "E mæ preferense",
+       "tooltip-pt-userpage": "A {{GENDER:|to}} pagina utente",
+       "tooltip-pt-mytalk": "A {{GENDER:|to}} paggina de discuscion",
+       "tooltip-pt-preferences": "E {{GENDER:|to}} preferençe",
        "tooltip-pt-watchlist": "A lista de pagine che ti g'hæ sotta osservaçion",
-       "tooltip-pt-mycontris": "E mæ contribuçioìn",
+       "tooltip-pt-mycontris": "A lista de {{GENDER:|to}} contribuçioin",
        "tooltip-pt-login": "Consegemmo a registraçión, ma a no l'è obrigatoia.",
        "tooltip-pt-logout": "Sciorti",
        "tooltip-pt-createaccount": "Se conseggia de registrase e de intrâ, sciben che no segge obligatoio",
        "tooltip-t-whatlinkshere": "Lista de tùtte e pagine che son colegæ a sta chì.",
        "tooltip-t-recentchangeslinked": "Ùrtimi càngi de pàgine colegæ a quésta",
        "tooltip-feed-atom": "Feed Atom pe sta pàgina",
-       "tooltip-t-contributions": "Lista de contribûssioîn de quest'utente",
+       "tooltip-t-contributions": "Lista de contribûssioin de {{GENDER:$1|questo|questa}} utente",
        "tooltip-t-emailuser": "Invia 'n messaggio e-mail a quest'utente",
        "tooltip-t-upload": "Carrega di file murtimediali",
        "tooltip-t-specialpages": "Lista de tùtte e pagine speçiâli",
index f49ffe4..39466e0 100644 (file)
        "special-characters-title-minus": "علامت منفی",
        "mw-widgets-dateinput-no-date": "هیچ داده‌ای انتخاب نشده",
        "mw-widgets-titleinput-description-new-page": "اێ وەڵگە هەنی(هالی)وجود نِئرێ",
-       "mw-widgets-titleinput-description-redirect": "گؤەڕانن/تغییر مسیر به $1",
-       "api-error-blacklisted": "لطفاً یک عنوان توصیفی متفاوت انتخاب کنید."
+       "mw-widgets-titleinput-description-redirect": "گؤەڕانن/تغییر مسیر به $1"
 }
index ded9f62..4afc969 100644 (file)
        "minoredit": "Tai smulkus pataisymas",
        "watchthis": "Stebėti šį puslapį",
        "savearticle": "Išsaugoti puslapį",
+       "savechanges": "Išsaugoti pakeitimus",
        "publishpage": "Skelbti puslapį",
+       "publishchanges": "Skelbti pakeitimus",
        "preview": "Peržiūra",
        "showpreview": "Rodyti peržiūrą",
        "showdiff": "Rodyti skirtumus",
        "action-read": "skaityti šį puslapį",
        "action-edit": "keisti šį puslapį",
        "action-createpage": "kurti puslapius",
-       "action-createtalk": "kurti aptarimų puslapius",
+       "action-createtalk": "sukurti šį diskusijų puslapį",
        "action-createaccount": "kurti šią naudotojo paskyrą",
        "action-autocreateaccount": "Automatiškai sukurti šią išorinę naudotojo paskyrą",
        "action-history": "peržiūrėti šio puslapio istoriją",
        "mw-widgets-dateinput-no-date": "Nepasirinkta data",
        "mw-widgets-titleinput-description-new-page": "puslapis dar neegzistuoja",
        "mw-widgets-titleinput-description-redirect": "nukreipti į $1",
-       "api-error-blacklisted": "Prašome pasirinkti kitą, aprašomąją antraštę.",
        "sessionmanager-tie": "Negalima kombinuoti kelių užklausų autentikacijos tipų: $1.",
        "sessionprovider-generic": "$1 sesijos",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sesijos su slapukais",
        "sessionprovider-nocookies": "Slapukai gali būti neaktyvuoti. Įsitikinkite, kad slapukai yra aktyvuoti ir pradėkite vėl.",
        "randomrootpage": "Atsitiktinis šakninis puslapis",
+       "log-action-filter-rights": "Teisių tipo keitimas:",
        "log-action-filter-all": "Visi",
        "log-action-filter-newusers-autocreate": "Automatinis kūrimas",
        "log-action-filter-protect-protect": "Apsauga"
index b440e89..5f16639 100644 (file)
        "right-passwordreset": "Apskatīt paroles atiestatīšanas e-pasta ziņojumus",
        "grant-group-email": "Sūtīt e-pastu",
        "grant-createaccount": "Izveidot kontu",
+       "grant-editmywatchlist": "Labot uzraugāmo rakstu sarakstu",
        "newuserlogpage": "Jauno dalībnieku reģistrs",
        "newuserlogpagetext": "Jauno lietotājvārdu reģistrs.",
        "rightslog": "Dalībnieku tiesību reģistrs",
        "special-characters-group-gujarati": "Gudžarati",
        "mw-widgets-dateinput-no-date": "Nav izvēlēts datums",
        "mw-widgets-titleinput-description-new-page": "lapa vēl nepastāv",
-       "api-error-blacklisted": "Lūdzu, izvēlieties citu, aprakstošu nosaukumu!",
        "authmanager-email-label": "E-pasts",
        "authmanager-email-help": "E-pasta adrese",
        "authmanager-realname-label": "Tavs īstais vārds",
index 0999c3e..153ab06 100644 (file)
@@ -21,7 +21,8 @@
                        "飞舞回堂前",
                        "Macofe",
                        "Bowleerin",
-                       "SolidBlock"
+                       "SolidBlock",
+                       "Suchichi02"
                ]
        },
        "tog-underline": "鏈墊線:",
        "editthispage": "纂",
        "create-this-page": "立",
        "delete": "刪",
-       "deletethispage": "刪",
+       "deletethispage": "刪是頁",
        "undeletethispage": "反刪此頁",
        "undelete_short": "還$1已刪",
        "viewdeleted_short": "察$1已刪",
        "edit-conflict": "纂突。",
        "edit-no-change": "爾之纂已略,由字無改也。",
        "postedit-confirmation-created": "其頁已建。",
-       "postedit-confirmation-saved": "汝之纂已成",
+       "postedit-confirmation-saved": "汝之纂已成",
        "edit-already-exists": "不建新頁。\n已存也。",
        "defaultmessagetext": "慣話文",
        "content-model-text": "純文本",
        "rcshowhidemine": "$1吾纂",
        "rcshowhidemine-show": "示",
        "rcshowhidemine-hide": "藏",
+       "rcshowhidecategorization-show": "示",
+       "rcshowhidecategorization-hide": "藏",
        "rclinks": "$2日內$1近易。<br />$3",
        "diff": "辨",
        "hist": "誌",
        "rc_categories_any": "任",
        "rc-change-size-new": "既纂,本文有$1字節",
        "newsectionsummary": "/* $1 */ 新節",
-       "rc-enhanced-expand": "示細(要 JavaScript)",
+       "rc-enhanced-expand": "示細",
        "rc-enhanced-hide": "藏細",
        "recentchangeslinked": "援引",
        "recentchangeslinked-feed": "援引",
        "contributions": "功績",
        "contributions-title": "$1之功績",
        "mycontris": "吾績",
+       "anoncontribs": "績",
        "contribsub2": "$1勛($2)",
        "nocontribs": "無勛及也。",
        "uctop": "(至頂)",
        "whatlinkshere-prev": "前$1",
        "whatlinkshere-next": "次$1",
        "whatlinkshere-links": "←佐",
-       "whatlinkshere-hideredirs": "$1",
+       "whatlinkshere-hideredirs": "$1",
        "whatlinkshere-hidetrans": "$1含",
        "whatlinkshere-hidelinks": "$1佐",
        "whatlinkshere-hideimages": "$1檔佐",
        "intentionallyblankpage": "此頁為白也,試速之用",
        "external_image_whitelist": " #同留<pre>\n#下(中之//)乃正表式\n#乃外(連)圖配之\n#配乃成像,非配則成連\n#有 # 之為注\n#無為大小之異也\n\n#入正表式。同留</pre>",
        "tag-filter": "[[Special:Tags|標]] 之濾:",
-       "tag-list-wrapper": "([[Special:Tags|簽]]: $2)",
+       "tag-list-wrapper": "([[Special:Tags|$1簽]]: $2)",
        "tags-title": "標",
        "tags-tag": "標名",
        "tags-source-header": "源",
        "sqlite-no-fts": "$1 不含全文之尋",
        "revdelete-restricted": "應限至有秩",
        "revdelete-unrestricted": "除限自有秩",
+       "logentry-newusers-create": "簿$1已{{GENDER:$2|增}}。",
        "rightsnone": "(凡)",
        "revdelete-summary": "摘",
        "searchsuggest-search": "尋",
index 19df826..8b597d6 100644 (file)
        "badarticleerror": "Ова дејство не може да се спроведе на оваа страница.",
        "cannotdelete": "Страницата или податотеката „$1“ не можеше да се избрише.\nМожеби некој друг веќе ја избришал.",
        "cannotdelete-title": "Не можам да ја избришам страницата „$1“",
-       "delete-hook-aborted": "Ð\91Ñ\80иÑ\88еÑ\9aеÑ\82о Ðµ Ð¿Ñ\80екинаÑ\82о Ñ\81о ÐºÑ\83ка.\nНе е дадено никакво образложение.",
+       "delete-hook-aborted": "Ð\91Ñ\80иÑ\88еÑ\9aеÑ\82о Ðµ Ð¿Ñ\80екинаÑ\82о Ñ\81о Ð¿Ñ\80еÑ\81Ñ\80еÑ\82ник.\nНе е дадено никакво образложение.",
        "no-null-revision": "Не можев да направам нова ништовна преработка на страницата „$1“",
        "badtitle": "Неисправен наслов",
        "badtitletext": "Бараниот наслов е грешен, празен или неисправно поврзан меѓујазичен или меѓупроектен наслов. \nМоже да содржи недопуштени знаци.",
        "moveddeleted-notice": "Оваа страница била претходно бришена.\nДневникот на бришења и преместувања за оваа страница е прикажан подолу за ваше дополнително информирање.",
        "moveddeleted-notice-recent": "За жал, страницава беше неодамна избришана (во последниве 24 часа).\nПодолу можете да го погледате дневникот на бришење и преместување.",
        "log-fulllog": "Преглед на целиот дневник",
-       "edit-hook-aborted": "УÑ\80едÑ\83ваÑ\9aеÑ\82о Ðµ Ð¿Ñ\80екинаÑ\82о Ñ\81о ÐºÑ\83ка.\nНе е дадено никакво образложение.",
+       "edit-hook-aborted": "УÑ\80едÑ\83ваÑ\9aеÑ\82о Ðµ Ð¿Ñ\80екинаÑ\82о Ñ\81о Ð¿Ñ\80еÑ\81Ñ\80еÑ\82ник.\nНе е дадено никакво образложение.",
        "edit-gone-missing": "Не можев да ја подновам страницата.\nВеројатно е избришана.",
        "edit-conflict": "Спротиставеност во уредувањето.",
        "edit-no-change": "Вашите уредувања беа игнорирани, бидејќи не се направени промени врз текстот.",
        "content-model-css": "CSS",
        "content-json-empty-object": "Празен објект",
        "content-json-empty-array": "Празна низа",
+       "deprecated-self-close-category": "Страници со неважечки самозатворени HTML-ознаки",
+       "deprecated-self-close-category-desc": "Страницава содржи неважечки самозатворени HTML-ознаки, како што се <code>&lt;b/></code> или <code>&lt;span/></code>. Нивното поведение наскоро ќе биде сменето, за да бидат во склад со определбите на HTML5. Ова значи дека се застарени и не треба да се употребуваат во викитекст.",
        "duplicate-args-warning": "<strong>Предупредување:</strong> [[:$1]] го повикува [[:$2]] со повеќе од една вредност за параметарот „$3“. Ќе се употреби само последната вредност.",
        "duplicate-args-category": "Страници што користат дуплирани аргументи во повикувања на шаблони",
        "duplicate-args-category-desc": "Страницава содржи повикувања на шаблони кои се дупликати на аргументи, како што се <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> или <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "difference-title-multipage": "$1 и $2: Разлика помеѓу страниците",
        "difference-multipage": "(Разлики помеѓу страници)",
        "lineno": "Ред $1:",
-       "compareselectedversions": "СпоÑ\80еди Ð¸Ð·Ð±Ñ\80ани преработки",
-       "showhideselectedversions": "Ð\9fÑ\80икажи/Ñ\81кÑ\80иÑ\98 Ð¸Ð·Ð±Ñ\80ани преработки",
+       "compareselectedversions": "СпоÑ\80еди Ð³Ð¸ Ð¸Ð·Ð±Ñ\80аниÑ\82е преработки",
+       "showhideselectedversions": "Ð\9fÑ\80икажи/Ñ\81кÑ\80иÑ\98 Ð³Ð¸ Ð¸Ð·Ð±Ñ\80аниÑ\82е преработки",
        "editundo": "откажи",
        "diff-empty": "(нема разлика)",
        "diff-multi-sameuser": "({{PLURAL:$1|Не е прикажана една меѓувремена преработка|Не се прикажани $1 меѓувремени преработки}} од истиот корисник)",
        "search-nonefound-thiswiki": "Нема резултати што одговараат на бараното на ова мрежно место.",
        "powersearch-legend": "Напредно пребарување",
        "powersearch-ns": "Пребарај во следниве именски простори:",
-       "powersearch-togglelabel": "Ð\9eдбеÑ\80и:",
+       "powersearch-togglelabel": "Ð\98збоÑ\80:",
        "powersearch-toggleall": "Сè",
        "powersearch-togglenone": "Ништо",
        "powersearch-remember": "Запoмни го изборот за идни пребарувања",
        "filename-tooshort": "Името на податотеката е прекратко.",
        "filetype-banned": "Овој тип на податотека е забранет.",
        "verification-error": "Оваа податотека не ја помина потврдата успешно.",
-       "hookaborted": "Ð\98змениÑ\82е Ñ\88Ñ\82о Ñ\81акаÑ\82е Ð´Ð° Ð³Ð¸ Ð½Ð°Ð¿Ñ\80авиÑ\82е Ñ\81е Ð¾Ñ\82кажани Ð¾Ð´ ÐºÑ\83ка на додатокот.",
+       "hookaborted": "Ð\98змениÑ\82е Ñ\88Ñ\82о Ñ\81акаÑ\82е Ð´Ð° Ð³Ð¸ Ð½Ð°Ð¿Ñ\80авиÑ\82е Ñ\81е Ð¾Ñ\82кажани Ð¾Ð´ Ð¿Ñ\80еÑ\81Ñ\80еÑ\82ник на додатокот.",
        "illegal-filename": "Такво име за податотеката на е дозволено.",
        "overwrite": "Не е дозволено запишување врз постоечка податотека.",
        "unknown-error": "Се појави непозната грешка.",
        "log-title-wildcard": "Пребарај наслови кои почнуваат со овој текст",
        "showhideselectedlogentries": "Прикажи/скриј одбрани записи",
        "log-edit-tags": "Измени ознаки на одредени дневнички записи",
-       "checkbox-select": "Ð\9eдбеÑ\80и: $1",
+       "checkbox-select": "Ð\98збоÑ\80: $1",
        "checkbox-all": "Сите",
        "checkbox-none": "Ништо",
        "checkbox-invert": "Избери обратно",
        "version-extensions": "Воспоставени додатоци",
        "version-skins": "Воспоставени рува",
        "version-specialpages": "Службени страници",
-       "version-parserhooks": "РаÑ\81Ñ\87ленÑ\83ваÑ\87ки ÐºÑ\83ки",
+       "version-parserhooks": "РаÑ\81Ñ\87ленÑ\83ваÑ\87ки Ð¿Ñ\80еÑ\81Ñ\80еÑ\82ниÑ\86и",
        "version-variables": "Променливи",
        "version-antispam": "Спречување на спам",
        "version-api": "Извршници",
        "version-other": "Друго",
        "version-mediahandlers": "Ракувачи со мултимедијални содржини",
-       "version-hooks": "Ð\9aÑ\83ки",
+       "version-hooks": "Ð\9fÑ\80еÑ\81Ñ\80еÑ\82ник",
        "version-parser-extensiontags": "Ознаки за расчленувачки додатоци",
-       "version-parser-function-hooks": "Ð\9aÑ\83ки на расчленувачки функции",
-       "version-hook-name": "Ð\98ме Ð½Ð° ÐºÑ\83ка",
+       "version-parser-function-hooks": "Ð\9fÑ\80еÑ\81Ñ\80еÑ\82ниÑ\86и на расчленувачки функции",
+       "version-hook-name": "Ð\9dазив Ð½Ð° Ð¿Ñ\80еÑ\81Ñ\80еÑ\82никоÑ\82",
        "version-hook-subscribedby": "Претплатено од",
        "version-version": "($1)",
        "version-no-ext-name": "[нема име]",
        "api-error-filetype-banned": "Овој тип на податотека е забранет.",
        "api-error-filetype-banned-type": "$1 не {{PLURAL:$4|е допуштен тип на податотека|се допуштени типови на податотека}}. {{PLURAL:$3|Допуштен е|Допуштени се}} $2.",
        "api-error-filetype-missing": "На податотеката ѝ недостасува наставка.",
-       "api-error-hookaborted": "Ð\98зменаÑ\82а Ñ\88Ñ\82о Ñ\81е Ð¾Ð±Ð¸Ð´Ð¾Ð²Ñ\82е Ð´Ð° Ñ\98а Ð½Ð°Ð¿Ñ\80авиÑ\82е Ðµ Ð¾Ñ\82кажана Ð¾Ð´ ÐºÑ\83ка за наставки.",
+       "api-error-hookaborted": "Ð\98зменаÑ\82а Ñ\88Ñ\82о Ñ\81е Ð¾Ð±Ð¸Ð´Ð¾Ð²Ñ\82е Ð´Ð° Ñ\98а Ð½Ð°Ð¿Ñ\80авиÑ\82е Ðµ Ð¾Ñ\82кажана Ð¾Ð´ Ð¿Ñ\80еÑ\81Ñ\80еÑ\82ник за наставки.",
        "api-error-http": "Внатрешна грешка: не можам да се поврзам со опслужувачот.",
        "api-error-illegal-filename": "Податотеката има недозволено име.",
        "api-error-internal-error": "Внатрешна грешка: нешто тргна наопаку при обработката на она што го подигате на викито.",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
        "mw-widgets-titleinput-description-new-page": "страницата сè уште не постои",
        "mw-widgets-titleinput-description-redirect": "пренасочување кон $1",
-       "api-error-blacklisted": "Одберете поинаков, описен наслов.",
        "sessionmanager-tie": "Не можете истовремено да користите повеќе типови барања за заверка: $1.",
        "sessionprovider-generic": "$1 седници",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "седници со колачиња",
        "log-action-filter-newusers": "Тип на создавање сметка:",
        "log-action-filter-patrol": "Тип на патролирање:",
        "log-action-filter-protect": "Тип на заштита:",
-       "log-action-filter-rights": "Тип на промена во правата",
-       "log-action-filter-suppress": "Тип на скривање",
+       "log-action-filter-rights": "Тип на промена во правата:",
+       "log-action-filter-suppress": "Тип на скривање:",
        "log-action-filter-upload": "Тип на подигање:",
        "log-action-filter-all": "Сите",
        "log-action-filter-block-block": "блокирање",
index 042c300..1714a3e 100644 (file)
        "mw-widgets-dateinput-no-date": "कोणताही दिनांक निवडला नाही",
        "mw-widgets-titleinput-description-new-page": "अद्याप पान अस्तित्वात नाही",
        "mw-widgets-titleinput-description-redirect": "$1ला पुनर्निर्देशित करा",
-       "api-error-blacklisted": "कुपया वेगळे वर्णनात्मक शीर्षक निवडा",
        "sessionmanager-tie": "हे एकत्रित करु शकत नाही,बहुविध विनंती अधिप्रमाणन प्रकार:$1",
        "sessionprovider-generic": "$1 सत्रे",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "कुकी-आधारीत सत्रे",
index bd9d358..f68b227 100644 (file)
        "minoredit": "Ini adalah suntingan kecil",
        "watchthis": "Pantau laman ini",
        "savearticle": "Simpan",
+       "publishpage": "Terbitkan",
+       "publishchanges": "Terbit perubahan",
        "preview": "Pralihat",
        "showpreview": "Paparkan pralihat",
        "showdiff": "Lihat perubahan",
        "mw-widgets-dateinput-no-date": "Tarik belum dipilih",
        "mw-widgets-titleinput-description-new-page": "laman belum wujud",
        "mw-widgets-titleinput-description-redirect": "melencong ke $1",
-       "api-error-blacklisted": "Sila pilih tajuk yang berbeza dan deskriptif.",
        "randomrootpage": "Laman akar rawak"
 }
index 6624844..27745d0 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Oggetto abbacante",
        "content-json-empty-array": "Array abbacante",
+       "deprecated-self-close-category": "Paggene ausanno nu tag HTML auto-nchiuse nun valido",
        "duplicate-args-warning": "<strong>Attenziò:</strong> [[:$1]] sta chiammanno [[:$2]] cu cchiù 'e nu volore p' 'o parametro \"$3\". Surtanto ll'urdemo valore s'auserrà.",
        "duplicate-args-category": "Paggene c'ausano argomiente dupprecate dint' 'e chiammate a 'e mudelle",
        "duplicate-args-category-desc": "'A paggena tene chiammate a mudelle c'ausassero argomiente dupprecate, comme p'esempio <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> o <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-no-date": "Nisciuna data scigliuta",
        "mw-widgets-titleinput-description-new-page": "'a pàggene nun esiste ancore",
        "mw-widgets-titleinput-description-redirect": "redirezionate ncopp' a $1",
-       "api-error-blacklisted": "Pe' piacere sciglite nu titolo differente e descrittivo.",
        "sessionmanager-tie": "Nun se ponno cumbinà 'e tipe 'e richiesta 'autenticaziona: $1.",
        "sessionprovider-generic": "$1 sessiune",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessiune basate ncopp' 'e cookie",
        "log-action-filter-patrol": "Tipo 'e verifica:",
        "log-action-filter-protect": "Tipo 'e protezione:",
        "log-action-filter-rights": "Tipo 'e cagnamiento 'e deritte",
-       "log-action-filter-suppress": "Tipo 'e suppressione",
+       "log-action-filter-suppress": "Tipo 'e suppressione:",
        "log-action-filter-upload": "Tipo 'e carreca:",
        "log-action-filter-all": "Tutte",
        "log-action-filter-block-block": "Blocco",
        "authprovider-confirmlink-message": "Verenno 'e tentative d'acciesso mò, l'utente ccà putessero avé nu cullegamento c' 'o cunto wiki d' 'o vuosto. A ffà cullegamento premmettesse appiccià 'o sistema 'e trasuta pe' bbìa 'e sti cunte. Pe' piacere sciglite 'e cunte addò vulite fà cullegamento.",
        "authprovider-confirmlink-request-label": "Cunte ca s'avesser'a cullegà",
        "authprovider-confirmlink-success-line": "$1: cullegato e apposto.",
-       "authprovider-confirmlink-failed": "'O cullegamento 'e ll'utenza nun è ngarrato sano sano: $1"
+       "authprovider-confirmlink-failed": "'O cullegamento 'e ll'utenza nun è ngarrato sano sano: $1",
+       "authprovider-confirmlink-ok-help": "Cuntinuà aropp'a fà veré 'e mmasciate 'errore 'e cullegamento."
 }
index b1fd528..73eef2a 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Tomt objekt",
        "content-json-empty-array": "Tom matrise",
+       "deprecated-self-close-category": "Sider som bruker ugyldige, balanserte HTML-tagger.",
+       "deprecated-self-close-category-desc": "Siden inneholder balanserte HTML-tagger slike som <code>&lt;b/></code> or <code>&lt;span/></code>. Oppførselen til disse vil snart endret for å være i samsvar med HTML-spesifikasjonen, og da vil de ikke kunne brukes som wikitekst.",
        "duplicate-args-warning": "<strong>Advarsel:</strong> [[:$1]] kaller [[:$2]] med flere enn en verdi for \"$3\"-parameteren. Bare den sist angitte verdien vil brukes.",
        "duplicate-args-category": "Sider med duplikate argumenter i malkall",
        "duplicate-args-category-desc": "Denne siden inneholder malkall med duplikate parametre, slik som <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> eller <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "feedback-close": "Utført",
        "feedback-external-bug-report-button": "Registrer en teknisk sak",
        "feedback-dialog-title": "Send tilbakemelding",
-       "feedback-dialog-intro": "Du kan benytte det enkle skjemaet under for å gi din tilbakemelding. Kommentaren din vil bli lagt til siden «$1» sammen med ditt brukernavn.",
+       "feedback-dialog-intro": "Bruk det enkle skjemaet under om du vil gi tilbakemelding. Kommentaren din vil bli lagt ut på siden «$1» sammen med brukernavnet ditt.",
        "feedback-error-title": "Feil",
        "feedback-error1": "Feil: Ukjent resultat fra API",
        "feedback-error2": "Feil: Redigering feilet",
        "feedback-message": "Melding:",
        "feedback-subject": "Emne:",
        "feedback-submit": "Send",
-       "feedback-terms": "Jeg er innforstått med at min nettleserinformasjon inkluderer nøyaktig informasjon om versjonen til min nettleser og mitt operativsystem og at dette vil bli delt offentlig sammen med min tilbakemelding.",
-       "feedback-termsofuse": "Jeg godtar å gi tilbakemelding i henhold til brukervilkårene.",
+       "feedback-terms": "Jeg er innforstått med at brukeragentinformasjonen min inkluderer nøyaktig informasjon om versjonen til nettleseren min og operativsystemet mitt, og at dette vil bli delt offentlig sammen med tilbakemeldingen min.",
+       "feedback-termsofuse": "Jeg godtar å gi tilbakemelding i tråd med bruksvilkårene.",
        "feedback-thanks": "Din tilbakemelding til siden \"[ $2  $1 ]\" er sendt. Takk skal du ha!",
        "feedback-thanks-title": "Takk!",
        "feedback-useragent": "Brukeragent",
        "mw-widgets-dateinput-placeholder-month": "ÅÅÅÅ-MM",
        "mw-widgets-titleinput-description-new-page": "siden eksisterer ikke ennå",
        "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
-       "api-error-blacklisted": "Vennligst velg en annen beskrivende tittel.",
        "sessionprovider-generic": "$1 sesjoner",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "informasjons&shy;kapsel-baserte sesjoner",
        "randomrootpage": "Tilfeldig rotside"
index 28e007f..7beefc3 100644 (file)
        "special-characters-group-khmer": "Khmer",
        "special-characters-title-endash": "liggend streepjen",
        "special-characters-title-emdash": "gedachtenstreepjen",
-       "special-characters-title-minus": "minteken",
-       "api-error-blacklisted": "Kies n aandere, beschrievende naam."
+       "special-characters-title-minus": "minteken"
 }
index 3d20c88..ee99f80 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Leeg object",
        "content-json-empty-array": "Lege reeks",
+       "deprecated-self-close-category": "Pagina's met ongeldige zelfsluitende HTML-tags",
        "duplicate-args-warning": "<strong>Waarschuwing:</strong> [[:$1]] roept [[:$2]] aan met meer dan één waarde voor de parameter \"$3\". Alleen de laatste waarde wordt gebruikt.",
        "duplicate-args-category": "Pagina's met dubbele sjabloonparameters",
        "duplicate-args-category-desc": "De pagina bevat aanroepen van sjablonen waarin hetzelfde argument meerdere keren wordt gebruikt, bijvoorbeeld <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> of <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "JJJJ-MM",
        "mw-widgets-titleinput-description-new-page": "pagina bestaat nog niet",
        "mw-widgets-titleinput-description-redirect": "doorverwijzing naar $1",
-       "api-error-blacklisted": "Kies een andere, beschrijvende naam.",
        "sessionmanager-tie": "Het is niet mogelijk om meerdere authenticatietypen voor verzoeken te combineren: $1.",
        "sessionprovider-generic": "$1-sessies",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "op cookies gebaseerde sessies",
index 2e9dfae..8182a4f 100644 (file)
        "nstab-category": "Kategori",
        "mainpage-nstab": "Hovudside",
        "nosuchaction": "Funksjonen finst ikkje",
-       "nosuchactiontext": "Handlinga som er oppgjeven i adressa er ugyldig.\nDu har kanskje stava adressa feil, eller følgt ei feil lenkja.\nDette kan òg skuldast ein feil i programvara som er nytta av {{SITENAME}}.",
+       "nosuchactiontext": "Handlinga som er oppgjeven i adressa er ugyldig.\nDu har kanskje stava adressa feil, eller følgt ei feil lenkje.\nDette kan òg skuldast ein feil i programvara som er nytta av {{SITENAME}}.",
        "nosuchspecialpage": "Det finst inga slik spesialside",
        "nospecialpagetext": "Du har bede om ei spesialside som ikkje finst. Lista over spesialsider finn du [[Special:SpecialPages|her]].",
        "error": "Feil",
        "sectioneditnotsupported-text": "Endring av bolkar er ikkje støtta på denne sida.",
        "permissionserrors": "Løyvefeil",
        "permissionserrorstext": "Du har ikkje tilgang til å gjere dette, {{PLURAL:$1|grunnen|grunnane}} til det finn du her:",
-       "permissionserrorstext-withaction": "Du har ikkje løyve til å $2 {{PLURAL:$1|på grunn av|av desse grunnane}}:",
+       "permissionserrorstext-withaction": "Du har ikkje løyve til å $2 {{PLURAL:$1|av di|av desse grunnane}}:",
        "recreate-moveddeleted-warn": "'''Åtvaring: Du attopprettar ei side som tidlegare har vorte sletta.'''\n\nDu bør tenkje over om det er høveleg å halde fram med å endre denne sida.\nSletteloggen for sida finn du her:",
        "moveddeleted-notice": "Sida er vorten sletta. Sletteloggen og flytteloggen er viste nedanfor for referanse.",
        "log-fulllog": "Sjå full loggføring",
        "search-relatedarticle": "Relatert",
        "searchrelated": "relatert",
        "searchall": "alle",
-       "showingresults": "Nedanfor er opp til {{PLURAL:$1|'''eitt'''|'''$1'''}} resultat som byrjar med nummer '''$2''' vist{{PLURAL:$1||e}}.",
+       "showingresults": "Nedanfor er opp til {{PLURAL:$1|<strong>eitt</strong>|<strong>$1</strong>}} resultat som byrjar med nummer <strong>$2</strong> vist{{PLURAL:$1||e}}.",
        "search-showingresults": "Resultat <strong>{{PLURAL:$4|$1|$1–$2}}</strong> av <strong>$3</strong>",
        "search-nonefound": "Ingen resultat svarte til førespurnaden.",
        "search-nonefound-thiswiki": "Det var ingen resultat som passa til spørjinga på denne nettstaden.",
        "protect-otherreason": "Anna/ytterlegare årsak:",
        "protect-otherreason-op": "Anna årsak",
        "protect-dropdown": "*Vanlege verneårsaker\n** Gjenteke hærverk\n** Gjenteke spam\n** Endringskrig\n** Side med mange vitjande",
-       "protect-edit-reasonlist": "Endrar verneårsaker",
+       "protect-edit-reasonlist": "Endra verneårsaker",
        "protect-expiry-options": "1 time:1 hour,1 dag:1 day,1 veke:1 week,2 veker:2 weeks,1 månad:1 month,3 månader:3 months,6 månader:6 months,1 år:1 year,endelaus:infinite",
        "restriction-type": "Tilgang:",
        "restriction-level": "Avgrensingsnivå:",
        "mw-widgets-dateinput-placeholder-month": "ÅÅÅÅ-MM",
        "mw-widgets-titleinput-description-new-page": "sida finst ikkje enno",
        "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
-       "api-error-blacklisted": "Vel eit anna namn som er meir skildrande.",
        "randomrootpage": "Tilfeldig rotsida"
 }
index 75c020f..8eb3af7 100644 (file)
        "tog-watchlisthidebots": "Amagar los cambiaments faits pels bòts dins la lista de seguiment",
        "tog-watchlisthideminor": "Amagar las modificacions menoras dins la lista de seguiment",
        "tog-watchlisthideliu": "Amaga, de la lista, las modificacions pels utilizaires connectats",
+       "tog-watchlistreloadautomatically": "Recargar automaticament la lista de seguiment quand las opcions de filtratge son modificadas (JavaScript requesit)",
        "tog-watchlisthideanons": "Amaga, de la lista, las modificacions anonimas",
        "tog-watchlisthidepatrolled": "Amagar las modificacions susvelhadas de la lista de seguiment",
+       "tog-watchlisthidecategorization": "Amagar la categorizacion de las paginas",
        "tog-ccmeonemails": "Me mandar una còpia dels corrièrs electronics que mandi als autres utilizaires",
        "tog-diffonly": "Far pas veire lo contengut de las paginas jos las difs",
        "tog-showhiddencats": "Afichar las categorias amagadas",
        "prefs-watchlist": "Lista de seguiment",
        "prefs-editwatchlist": "Modificar la lista de seguiment",
        "prefs-editwatchlist-label": "Modificar de títols de vòstra lista de seguiment",
+       "prefs-editwatchlist-edit": "Veire e levar de títols de vòstra lista de seguiment",
        "prefs-editwatchlist-raw": "Modificar la lista de seguiment en mòde brut",
        "prefs-editwatchlist-clear": "Escafar la lista de seguiment",
        "prefs-watchlist-days": "Nombre de jorns d'afichar dins la lista de seguiment :",
        "rows": "Rengadas :",
        "columns": "Colomnas :",
        "searchresultshead": "Recèrca",
-       "stub-threshold": "Limit superior pels <a href=\"#\" class=\"stub\">ligams cap als esbòsses</a> (octets) :",
+       "stub-threshold": "Limit pel formatatge dels ligams d’esbòs ($1) :",
        "stub-threshold-disabled": "Desactivat",
        "recentchangesdays": "Nombre de jorns d'afichar dins los darrièrs cambiaments :",
        "recentchangesdays-max": "(maximum $1 {{PLURAL:$1|jorn|jorns}})",
        "rightslogtext": "Aquò es un jornal dels cambiaments d'estatut d’utilizaire.",
        "action-read": "legir aquesta pagina",
        "action-edit": "modificar aquesta pagina",
-       "action-createpage": "crear de paginas",
-       "action-createtalk": "crear de paginas de discussion",
+       "action-createpage": "crear aquesta pagina",
+       "action-createtalk": "crear aquesta pagina de discussion",
        "action-createaccount": "crear aqueste compte d'utilizaire",
        "action-history": "afichar l’istoric d'aquesta pagina",
        "action-minoredit": "marcar aqueste cambiament coma menor",
        "special-characters-title-emdash": "jonhent em",
        "special-characters-title-minus": "signe mens",
        "randomrootpage": "Pagina raiç aleatòria",
+       "log-action-filter-rights": "Tipe de cambiament de dreits :",
+       "log-action-filter-suppress": "Tipe de supression :",
        "changecredentials": "Modificar las informacions d’identificacion"
 }
index 15b1059..750bc46 100644 (file)
        "jumpto": "Siirry",
        "jumptonavigation": "navigatsii",
        "jumptosearch": "eči",
-       "view-pool-error": "Pahakse mielekse palvelimet ollah ylikuormittunnuot täl hetkel. Liijan moni käyttäi oppiu tarkastella tädä sivuu. Vuota kodvaine, enne gu opit uvvessah.",
+       "view-pool-error": "Pahakse mielekse palvelimet ollah ylikuormittunnuot täl hetkel. Liijan moni käyttäi oppiu tarkastella tädä sivuu. Vuota kodvaine, enne gu opit uvvessah.\n\n$1",
        "generic-pool-error": "Pahakse mielekse palvelimet ollah ylikuormittunnuot nygöi. Liijan moni käyttäi oppiu tarkastella tädä sivuu.",
        "pool-timeout": "Lukittumizen vuotanduaigu on loppenuhes.",
        "pool-queuefull": "Ečindykyzymykzien tallendustila on täyzi",
index c0c1588..4f80dee 100644 (file)
        "noname": "ଆପଣ ଗୋଟିଏ ବୈଧ ଇଉଜର ନାମ ଦେଇନାହାନ୍ତି ।",
        "loginsuccesstitle": "ଠିକଭାବେ ଲଗ-ଇନ ହେଲା",
        "loginsuccess": "'''ଆପଣ {{SITENAME}}ରେ \"$1\" ନାମରେ ଲଗ-ଇନ କରିଛନ୍ତି ।'''",
-       "nosuchuser": "\"$1\" à¬¨à¬¾à¬®à¬°à­\87 à¬\95à­\87ହି à¬\9cଣà­\87 à¬¬à¬¿ à¬¸à¬­à­\8dà­\9f à¬¨à¬¾à¬¹à¬¾à¬¨à­\8dତି à¥¤\nà¬\87à¬\89à¬\9cର à¬¨à¬¾à¬® à¬\87à¬\82ରାà¬\9cà­\80 à¬\9bà­\8bà¬\9f à¬\93 à¬¬à¬¡à¬¼ à¬\85à¬\95à­\8dଷର à¬ªà­\8dରତି à¬¸à¬®à­\8dବà­\87ଦନଶà­\80ଳ à¥¤\nà¬\86ପଣ à¬¨à¬¿à¬\9cର à¬¬à¬¨à¬¾à¬¨ à¬ªà¬°à¬\96ି à¬¨à¬¿à¬\85ନà­\8dତà­\81, à¬\85ଥବା [[Special:CreateAccount|ନà­\82à¬\86 à¬\96ାତାà¬\9fିà¬\8f à¬¤à¬¿à¬\86ରି à¬\95ରନà­\8dତà­\81]] à¥¤",
+       "nosuchuser": "\"$1\" ନାମରେ କେହି ଜଣେ ବି ସଭ୍ୟ ନାହାନ୍ତି ।\nଇଉଜର ନାମ ଇଂରାଜୀ ଛୋଟ ଓ ବଡ଼ ଅକ୍ଷର ପ୍ରତି ସମ୍ବେଦନଶୀଳ ।\nବନାନ ପରଖି ନିଅନ୍ତୁ, ଅଥବା [[Special:CreateAccount|ନୂଆ ଖାତାଟିଏ ତିଆରି କରନ୍ତୁ]] ।",
        "nosuchusershort": "\"$1\" ନାମରେ କେହି ଜଣେ ବି ସଭ୍ୟ ନାହାନ୍ତି ।\nଆପଣ ବନାନ ପରଖି ନିଅନ୍ତୁ ।",
        "nouserspecified": "ଆପଣଙ୍କୁ ଇଉଜର ନାମଟିଏ ଦେବାକୁ ପଡ଼ିବ ।",
        "login-userblocked": "ଏହି ସଭ୍ୟଙ୍କୁ ଅଟକାଯାଇଛି । ଲଗ ଇନ କରିବାକୁ ଅନୁମତି ନାହିଁ ।",
        "special-characters-title-endash": "en ଡ୍ୟାସ",
        "special-characters-title-emdash": "em dash",
        "special-characters-title-minus": "ମେନୁଗୁଡିକର ଚିହ୍ନ",
-       "mw-widgets-titleinput-description-redirect": "$1କୁ ପୁନଃପ୍ରେରଣ କରିବେ",
-       "api-error-blacklisted": "ଦୟାକରି ଏକ ଅଲଗା, ବିବରଣୀ ଶିରୋନାମାରେ ରଖିବେ ।"
+       "mw-widgets-titleinput-description-redirect": "$1କୁ ପୁନଃପ୍ରେରଣ କରିବେ"
 }
index 1da711c..1612248 100644 (file)
        "botpasswords-label-restrictions": "Ograniczenia użytkowania:",
        "botpasswords-label-grants-column": "Przyznane",
        "botpasswords-bad-appid": "Nazwa bota \"$1\" nie jest prawidłowa.",
+       "botpasswords-insert-failed": "Nie udało się dodać robota o nazwie \"$1\". Czy był już wcześniej dodany?",
+       "botpasswords-update-failed": "Nie udało się zmienić robota o nazwie \"$1\". Czy został usunięty?",
        "botpasswords-created-title": "Hasło bota stworzone",
        "botpasswords-created-body": "Hasło bota \"$1\" użytkownika \"$2\" zostało utworzone.",
        "botpasswords-updated-title": "Hasło bota zaktualizowane",
        "botpasswords-updated-body": "Hasło bota \"$1\" użytkownika \"$2\" zostało zaktualizowane.",
        "botpasswords-deleted-title": "Hasło bota usunięte",
        "botpasswords-deleted-body": "Hasło bota \"$1\" użytkownika \"$2\" zostało usunięte.",
+       "botpasswords-newpassword": "Nowe hasło do zalogowania przez <strong>$1</strong> to <strong>$2</strong>. <em>Proszę je zapisać w celu wykorzystania w przyszłości.</em>",
        "botpasswords-no-provider": "BotPasswordsSessionProvider nie jest dostępne.",
        "botpasswords-restriction-failed": "Logowanie nie powiodło się z powodu ograniczeń na hasło bota.",
+       "botpasswords-invalid-name": "Określona nazwa użytkownika nie zawiera separatora hasła bota (\"$1\").",
        "botpasswords-not-exist": "Użytkownik \"$1\" nie ma hasła dla bota o nazwie \"$2\".",
        "resetpass_forbidden": "Hasła nie mogą zostać zmienione",
        "resetpass_forbidden-reason": "Hasła nie mogą zostać zmienione: $1",
        "passwordreset-emailsentusername": "Jeśli z tym kontem powiązany jest adres e‐mail, zostanie na niego wysłany e-mail do odzyskiwania hasła.",
        "passwordreset-emailsent-capture": "Wyświetlony poniżej e‐mail pozwalający na zresetowanie hasła został wysłany.",
        "passwordreset-emailerror-capture": "Poniżej wyświetlony e‐mail pozwalający na zresetowanie hasła został wygenerowany, ale nie udało się wysłać go do {{GENDER:$2|użytkownika|użytkowniczki}}: $1",
+       "passwordreset-emailsent-capture2": "{{PLURAL:$1|Został wysłany e-mail|Zostały wysłane e-mail}} z informacjami o resetowaniu hasła. {{PLURAL:$1|Użytkownik i hasło jest pokazany|Lista użytkowników i haseł jest pokazana}} poniżej.",
+       "passwordreset-emailerror-capture2": "Wysyłanie e-maila do {{GENDER:$2|użytkownika|użytkowniczki}} nie powiodło się: $1 {{PLURAL:$3|Użytkownik i hasło jest pokazany|Lista użytkowników i haseł jest pokazana}} poniżej.",
+       "passwordreset-nocaller": "Musi być podany wywołujący",
+       "passwordreset-nosuchcaller": "Wywołujący nie istnieje: $1",
        "passwordreset-invalideamil": "Nieprawidłowy adres e-mail",
        "passwordreset-nodata": "Nie podano ani nazwy użytkownika, ani adresu e-mail",
        "changeemail": "Zmiana lub usunięcie adresu e‐mail",
        "content-model-css": "CSS",
        "content-json-empty-object": "Pusty obiekt",
        "content-json-empty-array": "Pusta tablica",
+       "deprecated-self-close-category": "Strony zawierające nieprawidłowe samozamykające się znaczniki HTML",
+       "deprecated-self-close-category-desc": "Strona zawiera samozamykające się znaczniki HTML, takie jak <code>&lt;b/></code> lub <code>&lt;span/></code>. Ich zachowanie zmieni się na dostosowane do specyfikacji HTML5, więc ich użycie w wikikodzie jest zdeprecjonowane.",
        "duplicate-args-warning": "<strong>Ostrzeżenie:</strong> [[:$1]] wywołuje [[:$2]] z więcej niż jedną wartością dla parametru \"$3\". Tylko ostatnia podana wartość zostanie użyta.",
        "duplicate-args-category": "Strony zawierające wywołania szablonów z parametrami o takich samych nazwach",
        "duplicate-args-category-desc": "Strona zawiera szablony, które używają duplikatów argumentów, jak <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> lub <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "listgrants": "Uprawnienia",
        "listgrants-grant": "Uprawnienie",
        "listgrants-rights": "Uprawnienie",
-       "trackingcategories": "Śledzenie kategorii",
+       "trackingcategories": "Kategorie śledzące",
        "trackingcategories-summary": "Ta strona zawiera listę kategorii monitorujących wypełnianych automatycznie przez oprogramowanie MediaWiki. Nazwy kategorii można zmienić edytując odpowiednie komunikaty systemowe znajdujące się w przestrzeni nazw {{ns:8}}.",
        "trackingcategories-msg": "Śledzenie kategorii",
        "trackingcategories-name": "Nazwa komunikatu",
        "mw-widgets-dateinput-placeholder-month": "RRRR-MM",
        "mw-widgets-titleinput-description-new-page": "strona jeszcze nie istnieje",
        "mw-widgets-titleinput-description-redirect": "przekierowanie do $1",
-       "api-error-blacklisted": "Wybierz inny, opisowy tytuł.",
        "sessionmanager-tie": "Nie można łączyć kilku rodzajów uwierzytelniania dla zapytania: $1.",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sesje na podstawie cookie",
        "sessionprovider-nocookies": "Być może cookies są wyłączone. Upewnij się, że masz włączone cookies i zacznij od nowa.",
        "log-action-filter-newusers": "Typ utworzenia konta:",
        "log-action-filter-patrol": "Rodzaj patrolu:",
        "log-action-filter-protect": "Rodzaj zabezpieczenia:",
-       "log-action-filter-rights": "Typ zmiany uprawień",
-       "log-action-filter-suppress": "Typ ukrycia",
+       "log-action-filter-rights": "Typ zmiany uprawień:",
+       "log-action-filter-suppress": "Typ ukrycia:",
        "log-action-filter-upload": "Rodzaj przesłanych:",
        "log-action-filter-all": "Wszystkie",
        "log-action-filter-block-block": "Zablokowanie",
index 034efb7..73381f0 100644 (file)
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "a página ainda não existe",
        "mw-widgets-titleinput-description-redirect": "redirecionar para $1",
-       "api-error-blacklisted": "Por favor, escolha  um título descritivo diferente.",
        "randomrootpage": "Página raiz aleatória"
 }
index 7c3c87b..48cbc04 100644 (file)
        "noname": "Não especificou um nome de utilizador válido.",
        "loginsuccesstitle": "Autenticação bem sucedida",
        "loginsuccess": "'''Encontra-se agora ligado à {{SITENAME}} como \"$1\"'''.",
-       "nosuchuser": "Não existe nenhum utilizador com o nome \"$1\".\nOs nomes de utilizador são sensíveis à capitalização.\nVerifique a ortografia, ou [[Special:CreateAccount|crie uma nova conta]].",
+       "nosuchuser": "Não existe nenhum utilizador com o nome \"$1\".\nOs nomes de utilizador são sensíveis às letras maiúsculas e minúsculas.\nVerifique a ortografia, ou [[Special:CreateAccount|crie uma nova conta]].",
        "nosuchusershort": "Não existe um utilizador com o nome \"$1\". Verifique o nome que introduziu.",
        "nouserspecified": "Precisa de especificar um nome de utilizador.",
        "login-userblocked": "Este utilizador está bloqueado. Não é permitido o acesso.",
        "userpage-userdoesnotexist": "A conta \"<nowiki>$1</nowiki>\" não se encontra registada.\nVerifique se deseja realmente criar ou editar esta página, por favor.",
        "userpage-userdoesnotexist-view": "A conta de utilizador \"$1\" não está registada.",
        "blocked-notice-logextract": "Este utilizador está bloqueado.\nPara referência, o último registo de bloqueio é apresentado abaixo:",
-       "clearyourcache": "'''Nota:''' Após gravar, terá de limpar a ''cache'' do seu navegador para ver as alterações.\n*'''Firefox / Safari:''' Pressione ''Shift'' enquanto clica ''Recarregar'', ou pressione ''Ctrl-F5'' ou ''Ctrl-R'' (''⌘-R'' no Mac)\n*'''Google Chrome:''' Pressione ''Ctrl-Shift-R'' (''⌘-Shift-R'' no Mac)\n*'''Internet Explorer:''' Pressione ''Ctrl'' enquanto clica ''Recarregar'', ou pressione ''Ctrl-F5''\n*'''Opera:''' Limpe a ''cache'' em ''Ferramentas → Preferências'' (''Tools → Preferences'')",
+       "clearyourcache": "'''Nota:''' Após gravar, terá de limpar a ''cache'' do seu navegador para ver as alterações.\n*'''Firefox / Safari:''' Pressione ''Shift'' enquanto clica ''Recarregar'', ou pressione ''Ctrl-F5'' ou ''Ctrl-R'' (''⌘-R'' no Mac)\n*'''Google Chrome:''' Pressione ''Ctrl-Shift-R'' (''⌘-Shift-R'' no Mac)\n*'''Internet Explorer:''' Pressione ''Ctrl'' enquanto clica ''Recarregar'', ou pressione ''Ctrl-F5''\n*'''Opera:''' Ir para <em>Menu → Configurações</em> (<em>Opera → Preferências</em> no Mac) e, em seguida, <em>Privacidade e segurança → Limpar dados de navegação → Imagens e ficheiros em cache</em>.",
        "usercssyoucanpreview": "'''Dica:''' Use o botão \"{{int:showpreview}}\" para testar o seu novo CSS antes de gravar.",
        "userjsyoucanpreview": "'''Dica:''' Use o botão \"{{int:showpreview}}\" para testar o seu novo JavaScript antes de gravar.",
        "usercsspreview": "'''Lembre-se de que está apenas a antever o seu CSS particular.\nEste ainda não foi gravado!'''",
        "right-override-export-depth": "Exportar páginas incluindo páginas ligadas até uma profundidade de 5",
        "right-sendemail": "Enviar correio eletrónico a outros utilizadores",
        "right-passwordreset": "Ver mensagens de redefinição da palavra-passe",
-       "right-managechangetags": "Criar e eliminar [[Special:Tags|etiquetas]] da base de dados",
+       "right-managechangetags": "Criar e (des)ativar [[Special:Tags|etiquetas]]",
        "right-applychangetags": "Aplicar [[Special:Tags|etiquetas]] juntamente com as alterações",
        "right-changetags": "Adicionar ou remover [[Special:Tags|etiquetas]] arbitrárias em revisões e entradas de registo individuais",
+       "right-deletechangetags": "Eliminar [[Special:Tags|etiquetas]] da base de dados",
        "grant-generic": "Conjunto de direitos \"$1\"",
        "grant-group-page-interaction": "Interagir com páginas",
        "grant-group-file-interaction": "Interagir com conteúdo multimédia",
        "action-viewmyprivateinfo": "ver a sua informação privada",
        "action-editmyprivateinfo": "editar a sua informação privada",
        "action-editcontentmodel": "editar o modelo de conteúdo de uma página",
-       "action-managechangetags": "criar e eliminar etiquetas da base de dados",
+       "action-managechangetags": "criar e (des)ativar etiquetas",
        "action-applychangetags": "aplicar etiquetas juntamente com as suas alterações",
        "action-changetags": "adicionar e remover etiquetas arbitrárias em revisões e entradas de registo individuais",
        "nchanges": "$1 {{PLURAL:$1|alteração|alterações}}",
        "uploaded-script-svg": "Encontrou um elemento scriptable no ficheiro \"$1\" SVG carregado.",
        "uploaded-hostile-svg": "Encontrou-se um código CSS não seguro no elemento de estilo do arquivo SVG carregado.",
        "uploaded-event-handler-on-svg": "Não está permitido configurar atributos controladores de eventos <code>$1=\"$2\"</code> nos arquivos SVG.",
+       "uploaded-image-filter-svg": "Foi encontrado um filtro de imagem com a URL: <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG carregado.",
        "uploadscriptednamespace": "Este ficheiro SVG contém um domínio que não é permitido \"$1\".",
        "uploadinvalidxml": "Erro detectado na análise do XML do ficheiro carregado.",
        "uploadvirus": "O ficheiro contém um vírus! \nDetalhes: $1",
        "upload-options": "Opções de carregamento",
        "watchthisupload": "Vigiar este ficheiro",
        "filewasdeleted": "Um ficheiro com este nome foi carregado anteriormente e subsequentemente eliminado.\nDeverá verificar o $1 antes de voltar a enviá-lo.",
+       "filename-thumb-name": "Isto parece ser o título de uma miniatura. Por favor, não volte a carregar miniaturas na mesma wiki. Se este não é o caso, corrija o nome do ficheiro por um mais significativo, e que não possua o prefixo de miniatura.",
        "filename-bad-prefix": "O nome do ficheiro que está a enviar começa por '''\"$1\"''', um nome pouco explicativo, normalmente originado de forma automática por câmaras digitais. Escolha um nome de ficheiro mais explicativo, por favor.",
        "filename-prefix-blacklist": " #<!-- deixe esta linha exactamente como está --> <pre>\n# A sintaxe é a seguinte:\n#   * Tudo a partir do carácter \"#\" até ao fim da linha é um comentário\n#   * Todas as linhas não vazias são um prefixo para nomes de ficheiros típicos atribuídos automaticamente por câmaras digitais\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # alguns telefones móveis\nIMG # genérico\nJD # Jenoptik\nMGP # Pentax\nPICT # misc.\n #</pre> <!-- deixe esta linha exactamente como está -->",
        "upload-proto-error": "Protocolo incorreto",
        "upload-too-many-redirects": "A URL continha demasiados redirecionamentos",
        "upload-http-error": "Ocorreu um erro HTTP: $1",
        "upload-copy-upload-invalid-domain": "Não é possível realizar carregamentos remotos neste domínio.",
+       "upload-foreign-cant-upload": "Esta wiki não está configurada para carregar ficheiros para o repositório externo solicitado.",
        "upload-dialog-title": "Carregar ficheiro",
        "upload-dialog-button-cancel": "Cancelar",
        "upload-dialog-button-done": "Feito",
        "confirmemail_body_set": "Alguém, provavelmente você a partir do endereço IP $1,\ndefiniu o seu endereço de correio eletrónico como correio da conta \"$2\" em {{SITENAME}}.\n\nPara confirmar que esta conta é realmente sua e reativar\nas funcionalidades de correio eletrónico em {{SITENAME}},\nabra a seguinte ligação no seu navegador:\n\n$3\n\nCaso a conta *não* lhe pertença, abra a seguinte ligação\npara cancelar a confirmação do endereço de correio eletrónico:\n\n$5\n\nEste código de confirmação expira a $4.",
        "confirmemail_invalidated": "Confirmação de endereço de correio eletrónico cancelada",
        "invalidateemail": "Cancelar confirmação do correio eletrónico",
+       "notificationemail_subject_changed": "O endereço de correio eletrónico registado em {{SITENAME}} foi alterado",
+       "notificationemail_subject_removed": "O endereço de correio eletrónico registado em {{SITENAME}} foi removido",
+       "notificationemail_body_changed": "Alguém, provavelmente você, a partir do endereço IP $1, alterou o endereço de correio eletrónico da conta \"$2\" para \"$3\" em {{SITENAME}}.\n\nCaso não tenha alterado, contacte imediatamente um administrador do sítio.",
+       "notificationemail_body_removed": "Alguém, provavelmente você, a partir do endereço IP $1, eliminou o endereço de correio eletrónico da conta \"$2\" em {{SITENAME}}.\n\nCaso não tenha alterado, contacte imediatamente um administrador do sítio.",
        "scarytranscludedisabled": "[Transclusão interwikis foi impossibilitada]",
        "scarytranscludefailed": "[Não foi possível obter a predefinição a partir de $1]",
        "scarytranscludefailed-httpstatus": "[Não foi possível obter a predefinição a partir de $1: HTTP $2]",
        "feedback-useragent": "Agente de utilizador:",
        "searchsuggest-search": "Pesquisa",
        "searchsuggest-containing": "contendo...",
+       "api-error-autoblocked": "O seu endereço de IP foi bloqueado automaticamente, pois foi utilizado por um utilizador bloqueado.",
        "api-error-badaccess-groups": "Não tem permissão para enviar ficheiros para esta wiki.",
        "api-error-badtoken": "Erro interno: Chave incorrecta.",
+       "api-error-blocked": "Foi bloqueado de editar.",
        "api-error-copyuploaddisabled": "O carregamento de ficheiros por URL não foi possibilitado neste servidor.",
        "api-error-duplicate": "Já {{PLURAL:$1|existia outro ficheiro|existiam outros ficheiro}} na wiki com o mesmo conteúdo.",
        "api-error-duplicate-archive": "Já {{PLURAL:$1|estava outro ficheiro|estavam outros ficheiros}} no  site com o mesmo conteúdo, mas {{PLURAL:$1|foi|foram}} eliminados.",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "a página ainda não existe.",
        "mw-widgets-titleinput-description-redirect": "redirecionar para $1",
-       "api-error-blacklisted": "Escolha um título diferente e descritivo, por favor.",
        "sessionprovider-generic": "Sessões $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessões baseadas em cookie",
        "sessionprovider-nocookies": "Os cookies podem estar desativados. Certifique-se de que os cookies estão ativados e inicie novamente.",
        "log-action-filter-newusers": "Tipo de criação de conta:",
        "log-action-filter-patrol": "Tipo de patrulha:",
        "log-action-filter-protect": "Tipo de proteção:",
-       "log-action-filter-rights": "Tipo de alteração de privilégio",
-       "log-action-filter-suppress": "Tipo de supressão",
+       "log-action-filter-rights": "Tipo de alteração de privilégio:",
+       "log-action-filter-suppress": "Tipo de supressão:",
        "log-action-filter-upload": "Tipo de carregamento:",
        "log-action-filter-all": "Todas",
        "log-action-filter-block-block": "Bloquear",
        "authmanager-realname-label": "Nome verdadeiro",
        "authmanager-realname-help": "Nome verdadeiro do(a) utilizador(a)",
        "authprovider-resetpass-skip-label": "Ignorar",
+       "authpage-cannot-login": "Não é possível iniciar sessão.",
+       "authpage-cannot-login-continue": "Não é possível continuar a iniciar sessão. A sua sessão pode ter expirado.",
+       "authpage-cannot-create": "Não é possível iniciar a criação da conta.",
+       "authpage-cannot-create-continue": "Não é possível continuar a criação da conta. A sua sessão pode ter expirado.",
+       "cannotauth-not-allowed-title": "Permissão negada",
+       "cannotauth-not-allowed": "Não possui permissão para utilizar esta página",
        "changecredentials": "Alterar credenciais",
        "changecredentials-submit": "Alterar credenciais",
        "changecredentials-invalidsubpage": "$1 não é um tipo de credencial válido.",
        "removecredentials": "Remover credenciais",
        "removecredentials-submit": "Remover credenciais",
        "removecredentials-invalidsubpage": "$1 não é um tipo de credencial válido.",
+       "removecredentials-success": "As suas credenciais foram removidas.",
        "credentialsform-provider": "Tipo de credenciais:",
        "credentialsform-account": "Nome da conta:",
        "cannotlink-no-provider-title": "Não existem contas vinculáveis",
index 5ba5061..611106c 100644 (file)
        "content-model-json": "Name for the JSON content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}",
        "content-json-empty-object": "Used to represent an object with no properties on a JSON content model page.",
        "content-json-empty-array": "Used to represent an array with no values on a JSON content model page.",
+       "deprecated-self-close-category": "This message is used as a category name for a [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages are placed automatically if they contain invalid self-closed HTML tags, such as <code>&lt;b/></code> or <code>&lt;span/></code>.  The behavior of these will change soon to be consistent with the HTML5 specification, so their use in wikitext is deprecated.",
+       "deprecated-self-close-category-desc": "Invalid self-closed HTML tag category description. Shown on [[Special:TrackingCategories]].\n\nSee also:\n* {{msg-mw|deprecated-self-close-category}}",
        "duplicate-args-warning": "If a page calls a template and specifies the same argument more than once, such as <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>, this warning is displayed when previewing.\n\nParameters:\n* $1 - The calling page\n* $2 - The called template\n* $3 - The name of the duplicated argument",
        "duplicate-args-category": "This message is used as a category name for a [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages are placed automatically if they contain template calls that use duplicates of arguments, such as <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "duplicate-args-category-desc": "Duplicate arguments category description. Shown on [[Special:TrackingCategories]].\n\nSee also:\n* {{msg-mw|Duplicate-args-category}}",
        "apisandbox-jsonly": "Displayed as an error message if the browser does not have JavaScript enabled.",
        "apisandbox-api-disabled": "Displayed as an error message if the API is disabled on this site.",
        "apisandbox-intro": "Displayed (from JavaScript) as a header on [[Special:ApiSandbox]].",
-       "apisandbox-fullscreen": "JavaScript button label for enabling full-page mode.",
+       "apisandbox-fullscreen": "JavaScript button label for enabling full-page mode.\n\nSee https://phabricator.wikimedia.org/T129632#2465838 for details.",
        "apisandbox-fullscreen-tooltip": "Tooltip for the {{msg-mw|apisandbox-fullscreen}} button.",
-       "apisandbox-unfullscreen": "JavaScript button label for disabling full-page mode.",
+       "apisandbox-unfullscreen": "JavaScript button label for disabling full-page mode.\n\nSee https://phabricator.wikimedia.org/T129632#2465838 for details.",
        "apisandbox-unfullscreen-tooltip": "Tooltip for the {{msg-mw|apisandbox-unfullscreen}} button.",
        "apisandbox-submit": "JavaScript button label for submitting the request.",
        "apisandbox-reset": "JavaScript button label for clearing the form.\n{{Identical|Clear}}",
        "metadata-fields": "{{doc-important|Do not translate list items, only translate the text! So leave \"<code>* make</code>\" and the other items exactly as they are.}}\nThe sentences are for explanation only and are not shown to the user.",
        "metadata-langitem": "{{optional}}\nThis is used for constructing the list of translations when a metadata property is translated into multiple languages.\n\nParameters:\n* $1 - the value of the property (in one language)\n* $2 - the language name that this translation is for (or language code if language name cannot be determined)\n* $3 - (Unused) the language code",
        "metadata-langitem-default": "{{optional}}\nSimilar to \"metadata-langitem\" but for the case where a multilingual property has a default specified that does not specify what language the default is in. $1 is the value of the property.",
-       "exif-imagewidth": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n{{Identical|Width}}",
-       "exif-imagelength": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n{{Identical|Height}}",
+       "exif-imagewidth": "{{exif-qqq}}\n{{Identical|Width}}",
+       "exif-imagelength": "{{exif-qqq}}\n{{Identical|Height}}",
        "exif-bitspersample": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-compression": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis field labels what the compression of the image is. It is commonly seen in Tiff images. It uses messages like {{msg-mw|exif-compression-1}} for the value. [[w:TIFF#TIFF_Compression_Tag]] has information about this field.\n{{Related|Exif-compression}}",
+       "exif-compression": "{{exif-qqq}}\n\nThis field labels what the compression of the image is. It is commonly seen in Tiff images. It uses messages like {{msg-mw|exif-compression-1}} for the value. [[w:TIFF#TIFF Compression Tag]] has information about this field.\n\n{{Related|Exif-compression}}",
        "exif-photometricinterpretation": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-orientation": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nFor specific information on the orientation tag, see http://sylvana.net/jpegcrop/exif_orientation.html\n{{Related|Exif-orientation}}",
+       "exif-orientation": "{{exif-qqq}}\n\nFor specific information on the orientation tag, see http://sylvana.net/jpegcrop/exif_orientation.html\n\n{{Related|Exif-orientation}}",
        "exif-samplesperpixel": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-planarconfiguration": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee also:\n* {{msg-mw|Exif-planarconfiguration}}\n* {{msg-mw|Exif-planarconfiguration-1}}\n* {{msg-mw|Exif-planarconfiguration-2}}",
+       "exif-planarconfiguration": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-planarconfiguration}}\n* {{msg-mw|Exif-planarconfiguration-1}}\n* {{msg-mw|Exif-planarconfiguration-2}}",
        "exif-ycbcrsubsampling": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-ycbcrpositioning": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n{{Related|Exif-ycbcrpositioning}}",
-       "exif-xresolution": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis is the horizontal resolution in either dots/inch or dots/cm.",
-       "exif-yresolution": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis is the vertical resolution in either dots/inch or dots/cm.",
+       "exif-ycbcrpositioning": "{{exif-qqq}}\n{{Related|Exif-ycbcrpositioning}}",
+       "exif-xresolution": "{{exif-qqq}}\n\nThis is the horizontal resolution in either dots/inch or dots/cm.",
+       "exif-yresolution": "{{exif-qqq}}\n\nThis is the vertical resolution in either dots/inch or dots/cm.",
        "exif-stripoffsets": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
        "exif-rowsperstrip": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
        "exif-stripbytecounts": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
        "exif-primarychromaticities": "The chromaticity of the three primary colours of the image. Normally this tag is not necessary, since colour space is specified in the colour space information tag. This should probably be translated it as \"Chromaticity of primary colours\".\n\nExif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
        "exif-ycbcrcoefficients": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
        "exif-referenceblackwhite": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-datetime": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nNote, this message is also used for the XMP:ModifyDate property in XMP metadata. See page 35 of http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf\n\nDatetime is the time that the digital file was last changed.",
-       "exif-imagedescription": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis property is the description or caption of the image. It is used for the exif ImageDescription property, the dc:description property in XMP (see http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf ), and the iptc-iim 2:120 caption/abstract property ( http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf ).\n\nWhen an image has multiple differing descriptions, mediawiki follows the MWG guidelines when deciding which to show (Which typically means Exif takes precedence).",
-       "exif-make": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe Manufacturer of the digital camera (or scanner) that took the photo.",
-       "exif-model": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe model of camera (or scanner) used to take the picture.",
-       "exif-software": "Short for \"The software which was used to create or modify this image\".\n\nThe property can come from the Exif Software tag, PNG software chunk, iptc-iim 2:65 Software field, or XMP's xmp:CreatorTool field.\n\nExif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-artist": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis message labels the author or artist of the work. Usually this means who took the photograph, or who drew the picture. The corresponding value field most commonly contains a single author, however it can contain an ordered (or unordered depending on which metadata standard is used to store the information) list of authors. Sometimes the persons position is prefixed before their name such as \"Photographer, John Smith\". The exif standard recommends multiple authors be specified by \"position, Author 1; position for author 2, Author 2's name\" however this doesn't seem to happen in practice very often. If multiple authors are specified using a non-exif standard, then a billeted (or numbered) list is used.\n\nThis property can be specified by exif Artist tag, XMP's tiff:Artist, XMP's dc:creator, iptc-iim's 2:80 byline, PNG's author textual chunk, PNG's (unofficial) artist textual chunk. XMP's photoshop:AuthorsPosition and iptc 2:85 byline-title can also affect display of this property.\n{{Identical|Author}}",
+       "exif-datetime": "{{exif-qqq}}\n\nNote: this message is also used for the XMP:ModifyDate property in XMP metadata. See page 35 of http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf\n\nDatetime is the time that the digital file was last changed.",
+       "exif-imagedescription": "{{exif-qqq}}\n\nThis property is the description or caption of the image. It is used for the exif ImageDescription property, the dc:description property in XMP (see http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf ), and the iptc-iim 2:120 caption/abstract property ( http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf ).\n\nWhen an image has multiple differing descriptions, mediawiki follows the MWG guidelines when deciding which to show (Which typically means Exif takes precedence).",
+       "exif-make": "{{exif-qqq}}\n\nThe Manufacturer of the digital camera (or scanner) that took the photo.",
+       "exif-model": "{{exif-qqq}}\n\nThis tag specifies the model of camera (or scanner) used to take the picture.",
+       "exif-software": "{{exif-qqq}}\n\nThis tag is short for \"The software which was used to create or modify this image\".\n\nThe property can come from the Exif Software tag, PNG software chunk, iptc-iim 2:65 Software field, or XMP's xmp:CreatorTool field.",
+       "exif-artist": "{{exif-qqq}}\n\nThis message labels the author or artist of the work. Usually this means who took the photograph, or who drew the picture. The corresponding value field most commonly contains a single author, however it can contain an ordered (or unordered depending on which metadata standard is used to store the information) list of authors. Sometimes the persons position is prefixed before their name such as \"Photographer, John Smith\". The exif standard recommends multiple authors be specified by \"position, Author 1; position for author 2, Author 2's name\" however this doesn't seem to happen in practice very often. If multiple authors are specified using a non-exif standard, then a billeted (or numbered) list is used.\n\nThis property can be specified by exif Artist tag, XMP's tiff:Artist, XMP's dc:creator, iptc-iim's 2:80 byline, PNG's author textual chunk, PNG's (unofficial) artist textual chunk. XMP's photoshop:AuthorsPosition and iptc 2:85 byline-title can also affect display of this property.\n\n{{Identical|Author}}",
        "exif-copyright": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nLabel for information contained in exif Copyright tag, XMP dc:rights, IPTC-iim 2:116, or PNG copyright textual chunk.\n\nTypically the copyright statement for the photograph/drawing/video (such as ''(c) 2010 John Smith. Released under GFDL''). Sometimes contains license information. See also {{msg-mw|exif-copyrightowner}}",
-       "exif-exifversion": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nVersion of exif standard photo uses. Typically this is 2.22",
+       "exif-exifversion": "{{exif-qqq}}\n\nVersion of exif standard photo uses. Typically this is 2.22",
        "exif-flashpixversion": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nVersion of flashpix used. Flashpix is a format used for storing some types of metadata in image. It is not as commonly used as EXIF, and mediawiki currently cannot read Flashpix data.",
-       "exif-colorspace": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe colorspace of the photo. This tells the computer how to make the colours in the photo be more true to the original photo. Typical values for this are sRGB or uncalibrated. This only gives information on colour information given in the exif-colorspace property. However, colour information is often stored elsewhere in the photo.\n\nSee also:\n* {{msg-mw|Exif-colorspace}}\n* {{msg-mw|Exif-colorspace-1|optional}}\n* {{msg-mw|Exif-colorspace-65535}}",
-       "exif-componentsconfiguration": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis contains how the information in the picture is stored. This is most commonly Y, Cr, Cb to specify luma, red, blue. RGB is also possible to specify Red, Green, Blue.\n{{Related|Exif-componentsconfiguration}}",
+       "exif-colorspace": "{{exif-qqq}}\n\nThe colorspace of the photo. This tells the computer how to make the colours in the photo be more true to the original photo. Typical values for this are sRGB or uncalibrated. This only gives information on colour information given in the exif-colorspace property. However, colour information is often stored elsewhere in the photo.\n\nSee also:\n* {{msg-mw|Exif-colorspace}}\n* {{msg-mw|Exif-colorspace-1|optional}}\n* {{msg-mw|Exif-colorspace-65535}}",
+       "exif-componentsconfiguration": "{{exif-qqq}}\n\nThis contains how the information in the picture is stored. This is most commonly Y, Cr, Cb to specify luma, red, blue. RGB is also possible to specify Red, Green, Blue.\n\n{{Related|Exif-componentsconfiguration}}",
        "exif-compressedbitsperpixel": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-pixelxdimension": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n{{Identical|Image width}}",
+       "exif-pixelxdimension": "{{exif-qqq}}\n{{Identical|Image width}}",
        "exif-pixelydimension": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n{{Identical|Image height}}",
-       "exif-usercomment": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nComments by user. Sometimes used like ImageDescription when the ImageDescription contained non-ascii characters. (Technically ImageDescription is supposed to contain ascii characters. In practice utf-8 is used in ImageDescription, so this field isn't used too much.)",
+       "exif-usercomment": "{{exif-qqq}}\n\nComments by user. Sometimes used like ImageDescription when the ImageDescription contained non-ascii characters. (Technically ImageDescription is supposed to contain ascii characters. In practice utf-8 is used in ImageDescription, so this field isn't used too much.)",
        "exif-relatedsoundfile": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSome cameras offer the option to record an audio \"memo\" for the photo they just took. If the user did that, the name of the file is labelled with this message.",
        "exif-datetimeoriginal": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe date and time when the original image data was generated. For example if it was a painting from 1773, scanned in to a computer in 2007, the datetimeoriginal would be 1773 and {{msg-mw|exif-datetimedigitized}} would have the 2007 date.",
        "exif-datetimedigitized": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe date and time when the image was stored as digital data.",
-       "exif-subsectime": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\n'DateTime subseconds' shows the detail of the fraction of a second (1/100s) at which the file was changed, when the tag {{msg-mw|Exif-datetime}} is recorded to the whole second.",
-       "exif-subsectimeoriginal": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis tag shows the detail of the fraction of a second (1/100s) at which the file data was originally generated, when the tag {{msg-mw|Exif-datetimeoriginal}} is recorded to the whole second.",
-       "exif-subsectimedigitized": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis tag shows the detail of the fraction of a second (1/100s) at which the file was stored as digital data, when the tag {{msg-mw|Exif-datetimedigitized}} is recorded to the whole second.",
-       "exif-exposuretime": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe exposure time. Number of (or fraction of) seconds the film was exposed to light. The value for this property is formatted using {{msg-mw|exif-exposuretime-format}}",
-       "exif-exposuretime-format": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nParameters:\n* $1 - the exposure time written as a fraction of a second, for example 1/640 of a second\n* $2 - the exposure time written as a decimal, for example 0.0015625\n\n'sec' is the abbreviation used in English for the unit of time 'second'.",
-       "exif-fnumber": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe [[w:F_number|F number]] is the relative aperture of the camera.",
+       "exif-subsectime": "{{exif-qqq}}\n\n'DateTime subseconds' shows the detail of the fraction of a second (1/100s) at which the file was changed, when the tag {{msg-mw|Exif-datetime}} is recorded to the whole second.",
+       "exif-subsectimeoriginal": "{{exif-qqq}}\n\nThis tag shows the detail of the fraction of a second (1/100s) at which the file data was originally generated, when the tag {{msg-mw|Exif-datetimeoriginal}} is recorded to the whole second.",
+       "exif-subsectimedigitized": "{{exif-qqq}}\n\nThis tag shows the detail of the fraction of a second (1/100s) at which the file was stored as digital data, when the tag {{msg-mw|Exif-datetimedigitized}} is recorded to the whole second.",
+       "exif-exposuretime": "{{exif-qqq}}\n\nThe exposure time. Number of (or fraction of) seconds the film was exposed to light. The value for this property is formatted using {{msg-mw|exif-exposuretime-format}}",
+       "exif-exposuretime-format": "{{exif-qqq}}\n\nParameters:\n* $1 - the exposure time written as a fraction of a second, for example 1/640 of a second\n* $2 - the exposure time written as a decimal, for example 0.0015625\n\n'sec' is the abbreviation used in English for the unit of time 'second'.",
+       "exif-fnumber": "{{exif-qqq}}\n\nThe [[w:F number|F number]] is the relative aperture of the camera.",
        "exif-fnumber-format": "{{optional}}\nExif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nParameters:\n* $1 - a number\nNote:\n* f is the abbreviation used in English for \"f-number\".",
-       "exif-exposureprogram": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nHow the camera figured out what exposure to use. (If it was manually set, if its optimizing for fast shutter speed, etc).\n{{Related|Exif-exposureprogram}}",
+       "exif-exposureprogram": "{{exif-qqq}}\n\nHow the camera figured out what exposure to use. (If it was manually set, if its optimizing for fast shutter speed, etc).\n\n{{Related|Exif-exposureprogram}}",
        "exif-spectralsensitivity": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nHow sensitive each channel (colour) of the photo is to light. This tag is almost never used.",
        "exif-isospeedratings": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe iso speed of the film used in the camera. This is basically a measure of how sensitive the film in the camera is to light.",
        "exif-shutterspeedvalue": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\n[[w:Shutter_speed|Shutter speed]] is the time that the camera shutter is open.\n\nThis is the shutter speed measured in APEX units (negative base 2 log of shutter speed in seconds). See {{msg-mw|exif-exposuretime}} for this property in more traditional units of seconds.",
-       "exif-aperturevalue": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe [[w:Aperture|aperture]] of a camera is the hole through which light shines. This message can be translated 'Aperture width'. Note, this is measured in APEX units which is 2*log<sub>2</sub>(f-number) . See {{msg-mw|exif-fnumber}} for this value in more traditional units.",
+       "exif-aperturevalue": "{{exif-qqq}}\n\nThe [[w:Aperture|aperture]] of a camera is the hole through which light shines. This message can be translated 'Aperture width'. Note, this is measured in APEX units which is 2*log<sub>2</sub>(f-number) . See {{msg-mw|exif-fnumber}} for this value in more traditional units.",
        "exif-brightnessvalue": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nHow intense the illumination of the scene photographed is. Measured in APEX brightness units. See Annex C of Exif standard for details on the measurement system in use.",
        "exif-exposurebiasvalue": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nAnother term for [[w:Exposure_bias|'exposure bias']] is 'exposure compensation'.",
        "exif-maxaperturevalue": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe 'land' in a camera refers possibly to the inner surface of the barrel of the lens. An alternative phrasing for this message could perhaps be 'maximum width of the land aperture'.",
        "exif-subjectdistance": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThe subject of a photograph is the person or thing on which the camera focuses. 'Subject distance' is the distance to the subject given in meters.",
-       "exif-meteringmode": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee [[w:Metering_mode|Wikipedia article]] on metering mode.\n{{Related|Exif-meteringmode}}",
-       "exif-lightsource": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n{{Related|Exif-lightsource}}",
-       "exif-flash": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee this [[w:en:Flash_(photography)|Wikipedia article]] for an explanation of the term.\n{{Related|Exif-flash}}\n{{Identical|Flash}}",
+       "exif-meteringmode": "{{exif-qqq}}\n\nSee [[w:Metering mode|Wikipedia article]] on metering mode.\n\n{{Related|Exif-meteringmode}}",
+       "exif-lightsource": "{{exif-qqq}}\n\n{{Related|Exif-lightsource}}",
+       "exif-flash": "{{exif-qqq}}\n\nSee this [[w:en:Flash (photography)|Wikipedia article]] for an explanation of the term.\n\n{{Related|Exif-flash}}\n{{Identical|Flash}}",
        "exif-focallength": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee this [[w:en:Focal_length_(photography)|Wikipedia article]] for an explanation of the term.",
        "exif-focallength-format": "{{optional}}\nExif is a format for storing metadata in image files. See this [http://en.wikipedia.org/wiki/Exchangeable_image_file_format Wikipedia article] and the example at the bottom of [http://commons.wikimedia.org/wiki/File:Phalacrocorax-auritus-020.jpg this page on Commons]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nParameters:\n* $1 - a number\nNote:\n* mm is the abbreviation used in English for the unit of measurement of length \"millimeter\".",
-       "exif-subjectarea": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nThis exif property contains the position of the main subject. The first two numbers is the position of the subject in the picture in pixels from the upper left corner. If a third number is specified, it is a circle centred at the first two numbers. If four numbers are specified, the first two are coordinates of the centre of the subject as before, the third is the width of the rectangle, and the fourth is the height of the rectangle. It is rare for a photo to use this tag.",
+       "exif-subjectarea": "{{exif-qqq}}\n\nThis exif property contains the position of the main subject. The first two numbers is the position of the subject in the picture in pixels from the upper left corner. If a third number is specified, it is a circle centred at the first two numbers. If four numbers are specified, the first two are coordinates of the centre of the subject as before, the third is the width of the rectangle, and the fourth is the height of the rectangle. It is rare for a photo to use this tag.",
        "exif-flashenergy": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nHow bright the flash is in beam candle power seconds.",
        "exif-focalplanexresolution": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nIndicates the number of pixels in the image width (X) direction per FocalPlaneResolutionUnit on the camera focal plane.",
        "exif-focalplaneyresolution": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-focalplaneresolutionunit": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee also:\n* {{msg-mw|Exif-focalplaneresolutionunit-2}}",
+       "exif-focalplaneresolutionunit": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-focalplaneresolutionunit-2}}",
        "exif-subjectlocation": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSame as {{msg-mw|exif-subjectarea}} but only ever has two numbers as a value.",
        "exif-exposureindex": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].",
-       "exif-sensingmethod": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n{{Related|Exif-sensingmethod}}",
+       "exif-sensingmethod": "{{exif-qqq}}\n{{Related|Exif-sensingmethod}}",
        "exif-filesource": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nDetermines if the image was recorded by a digital camera adhering to DSC standard (which is almost all digital cameras).",
-       "exif-scenetype": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nIf the image is directly photographed (taken by a digital camera).\n\nSee also:\n* {{msg-mw|Exif-scenetype}}\n* {{msg-mw|Exif-scenetype-1}}",
-       "exif-customrendered": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee also Wikipedia on [[w:Image_processing|image processing]].\n\nSee also:\n* {{msg-mw|Exif-customrendered}}\n* {{msg-mw|Exif-customrendered-0}}\n* {{msg-mw|Exif-customrendered-1}}",
-       "exif-exposuremode": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee also Wikipedia on [[w:en:Exposure_(photography)|exposure in photography]]. This tag shows if the photo's exposure was manually set or automatically determined.\n{{Related|Exif-exposuremode}}",
-       "exif-whitebalance": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee also Wikipedia on [[w:Color_balance|color balance]].\n\nSee also:\n* {{msg-mw|Exif-whitebalance}}\n* {{msg-mw|Exif-whitebalance-0}}\n* {{msg-mw|Exif-whitebalance-1}}",
+       "exif-scenetype": "{{exif-qqq}}\n\nThis tag indicates whether the image is directly photographed (taken by a digital camera).\n\nSee also:\n* {{msg-mw|Exif-scenetype}}\n* {{msg-mw|Exif-scenetype-1}}",
+       "exif-customrendered": "{{exif-qqq}}\n\nSee also the Wikipedia article on [[w:Image processing|image processing]].\n\nSee also:\n* {{msg-mw|Exif-customrendered}}\n* {{msg-mw|Exif-customrendered-0}}\n* {{msg-mw|Exif-customrendered-1}}",
+       "exif-exposuremode": "{{exif-qqq}}\n\nThis tag shows if the photo's exposure was manually set or automatically determined. See the Wikipedia article on [[w:en:Exposure (photography)|exposure in photography]] for more details.\n\n{{Related|Exif-exposuremode}}",
+       "exif-whitebalance": "{{exif-qqq}}\n\nSee also the Wikipedia article on [[w:Color balance|color balance]].\n\nSee also:\n* {{msg-mw|Exif-whitebalance}}\n* {{msg-mw|Exif-whitebalance-0}}\n* {{msg-mw|Exif-whitebalance-1}}",
        "exif-digitalzoomratio": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee also Wikipedia on [[w:Digital_zoom|digital zoom]].",
        "exif-focallengthin35mmfilm": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\nSee also Wikipedia on [[w:Focal_length#In_photography|focal length]].",
-       "exif-scenecapturetype": "{{Related|Exif-scenecapturetype}}",
-       "exif-gaincontrol": "Gain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n{{Related|Exif-gaincontrol}}",
-       "exif-contrast": "{{Related|Exif-contrast}}",
-       "exif-saturation": "{{Related|Exif-saturation}}",
-       "exif-sharpness": "{{Related|Exif-sharpness}}",
+       "exif-scenecapturetype": "{{exif-qqq}}\n{{Related|Exif-scenecapturetype}}",
+       "exif-gaincontrol": "{{exif-qqq}}\n\nGain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n\n{{Related|Exif-gaincontrol}}",
+       "exif-contrast": "{{exif-qqq}}\n{{Related|Exif-contrast}}",
+       "exif-saturation": "{{exif-qqq}}\n{{Related|Exif-saturation}}",
+       "exif-sharpness": "{{exif-qqq}}\n{{Related|Exif-sharpness}}",
        "exif-devicesettingdescription": "The section header shown above device settings extracted from a file's EXIF data on the file's page.",
-       "exif-subjectdistancerange": "{{Related|Exif-subjectdistancerange}}",
+       "exif-subjectdistancerange": "{{exif-qqq}}\n{{Related|Exif-subjectdistancerange}}",
        "exif-imageuniqueid": "A unique identifier for the image in the form of a 128-bit hexadecimal string. See http://www.exif.org/Exif2-2.PDF for details on exif properties.",
        "exif-gpsversionid": "Version of the GPS IFD used to store location information. This is usually 2.2.0.0",
-       "exif-gpslatituderef": "In older versions of mediawiki this referred to if the latitude was North or South. This is no longer used in modern versions of mediawiki except for when using a foreign image repository that is using an older version of mediawiki since the information is now contained in {{msg-mw|exif-gpslatitude}}.\n{{Related|Exif-gpslatitude}}",
-       "exif-gpslatitude": "The latitude of the location from where the picture was taken from.\n{{Related|Exif-gpslatitude}}\n{{Identical|Latitude}}",
-       "exif-gpslongituderef": "Same as {{msg-mw|exif-gpslatituderef}} but for longitude.\n\n{{Related|Exif-gpslatitude}}",
-       "exif-gpslongitude": "The longitude of the location from where the picture was taken from.\n{{Related|Exif-gpslatitude}}\n{{Identical|Longitude}}",
+       "exif-gpslatituderef": "{{exif-qqq}}\n\nIn older versions of mediawiki this referred to if the latitude was North or South. This is no longer used in modern versions of mediawiki except for when using a foreign image repository that is using an older version of mediawiki since the information is now contained in {{msg-mw|exif-gpslatitude}}.\n\n{{Related|Exif-gpslatitude}}",
+       "exif-gpslatitude": "{{exif-qqq}}\n\nThe latitude of the location from where the picture was taken from.\n\n{{Related|Exif-gpslatitude}}\n{{Identical|Latitude}}",
+       "exif-gpslongituderef": "{{exif-qqq}}\n\nSame as {{msg-mw|exif-gpslatituderef}} but for longitude.\n\n{{Related|Exif-gpslatitude}}",
+       "exif-gpslongitude": "{{exif-qqq}}\n\nThe longitude of the location from where the picture was taken from.\n\n{{Related|Exif-gpslatitude}}\n{{Identical|Longitude}}",
        "exif-gpsaltituderef": "No longer used except for when using foreign image repository with old version of mediawiki. 0 for above sea level, 1 for below sea level.",
        "exif-gpsaltitude": "Altitude in meters that the image was taken at.",
        "exif-gpstimestamp": "Time (does not include date) that GPS measurement was taken, in UTC. Since often this is at the same time as photo was taken, this is sometimes more reliable than {{msg-mw|exif-datetimeoriginal}}.",
        "exif-gpssatellites": "Label for EXIF information. Indicates the GPS satellites used for measurements.",
-       "exif-gpsstatus": "See also:\n* {{msg-mw|Exif-gpsstatus-a}}\n* {{msg-mw|Exif-gpsstatus-v}}",
-       "exif-gpsmeasuremode": "Is the measurement 2D (latitude and longitude) or 3D (latitude, longitude, and altitude).\n\nSee also:\n* {{msg-mw|Exif-gpsmeasuremode-2}}\n* {{msg-mw|Exif-gpsmeasuremode-3}}",
-       "exif-gpsdop": "How accurate the GPS information is. See http://en.wikipedia.org/wiki/Dilution_of_precision_(GPS)\n{{Related|Exif-gpsdop}}",
-       "exif-gpsspeedref": "{{Related|Exif-gpsspeed}}",
-       "exif-gpsspeed": "{{Related|Exif-gpsspeed}}",
-       "exif-gpstrackref": "See also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearing}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
-       "exif-gpstrack": "See also:\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearing}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
-       "exif-gpsimgdirectionref": "See also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsdestbearing}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
-       "exif-gpsimgdirection": "See also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearing}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
+       "exif-gpsstatus": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpsstatus-a}}\n* {{msg-mw|Exif-gpsstatus-v}}",
+       "exif-gpsmeasuremode": "{{exif-qqq}}\n\nThis tag indicates whether the measurement 2D (latitude and longitude) or 3D (latitude, longitude, and altitude).\n\nSee also:\n* {{msg-mw|Exif-gpsmeasuremode-2}}\n* {{msg-mw|Exif-gpsmeasuremode-3}}",
+       "exif-gpsdop": "{{exif-qqq}}\n\nHow accurate the GPS information is. See [[wikipedia:Dilution of precision (GPS)]].\n\n{{Related|Exif-gpsdop}}",
+       "exif-gpsspeedref": "{{exif-qqq}}\n{{Related|Exif-gpsspeed}}",
+       "exif-gpsspeed": "{{exif-qqq}}\n{{Related|Exif-gpsspeed}}",
+       "exif-gpstrackref": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearing}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
+       "exif-gpstrack": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearing}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
+       "exif-gpsimgdirectionref": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsdestbearing}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
+       "exif-gpsimgdirection": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearing}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
        "exif-gpsmapdatum": "Label for EXIF information. Indicates the geodetic survey data used by the GPS receiver.",
-       "exif-gpsdestlatituderef": "{{Related|Exif-gpslatitude}}",
-       "exif-gpsdestlatitude": "The latitude of the location shown in the picture, if it is different from latitude of the camera location. See {{msg-mw|exif-gpslatitude}}.\n{{Related|Exif-gpslatitude}}\n{{Identical|Latitude}}",
-       "exif-gpsdestlongituderef": "{{Related|Exif-gpslatitude}}",
-       "exif-gpsdestlongitude": "The longitude of the location shown in the picture, if it is different from longitude of the camera location. See {{msg-mw|exif-gpslongitude}}.\n{{Related|Exif-gpslatitude}}\n{{Identical|Longitude}}",
-       "exif-gpsdestbearingref": "See also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearing}}",
-       "exif-gpsdestbearing": "See also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
-       "exif-gpsdestdistanceref": "I think \"reference\" stands for \"unit\". See {{msg-mw|Exif-gpsspeedref}}\n{{Related|Exif-gpsdestdistance}}",
-       "exif-gpsdestdistance": "{{Related|Exif-gpsdestdistance}}",
+       "exif-gpsdestlatituderef": "{{exif-qqq}}\n{{Related|Exif-gpslatitude}}",
+       "exif-gpsdestlatitude": "{{exif-qqq}}\n\nThe latitude of the location shown in the picture, if it is different from latitude of the camera location. See {{msg-mw|exif-gpslatitude}}.\n\n{{Related|Exif-gpslatitude}}\n{{Identical|Latitude}}",
+       "exif-gpsdestlongituderef": "{{exif-qqq}}\n{{Related|Exif-gpslatitude}}",
+       "exif-gpsdestlongitude": "{{exif-qqq}}\n\nThe longitude of the location shown in the picture, if it is different from longitude of the camera location. See {{msg-mw|exif-gpslongitude}}.\n\n{{Related|Exif-gpslatitude}}\n{{Identical|Longitude}}",
+       "exif-gpsdestbearingref": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearing}}",
+       "exif-gpsdestbearing": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpstrack}}\n* {{msg-mw|Exif-gpstrackref}}\n* {{msg-mw|Exif-gpsimgdirection}}\n* {{msg-mw|Exif-gpsimgdirectionref}}\n* {{msg-mw|Exif-gpsdestbearingref}}",
+       "exif-gpsdestdistanceref": "{{exif-qqq}}\n\nIndicates the unit used to express the distance to the destination point. Values are typically \"K\", \"M\" or \"N\", standing for kilometers, miles and nautical miles, respectively. See also {{msg-mw|Exif-gpsspeedref}}.\n\n{{Related|Exif-gpsdestdistance}}",
+       "exif-gpsdestdistance": "{{exif-qqq}}\n{{Related|Exif-gpsdestdistance}}",
        "exif-gpsprocessingmethod": "Label for EXIF information. A character string recording the name of the method used for location finding.",
        "exif-gpsareainformation": "Label for EXIF information. Contains a character string recording the name of the GPS area.",
-       "exif-gpsdatestamp": "Date (does not generally include time unless recorded in XMP) that GPS measurement was taken, in UTC. Since often this is at the same date as photo was taken, this is sometimes more reliable than {{msg-mw|exif-datetimeoriginal}}.",
+       "exif-gpsdatestamp": "{{exif-qqq}}\n\nDate (does not generally include time unless recorded in XMP) that GPS measurement was taken, in UTC. Since often this is at the same date as photo was taken, this is sometimes more reliable than {{msg-mw|exif-datetimeoriginal}}.",
        "exif-gpsdifferential": "Label for EXIF information. Indicates whether differential correction is applied to the GPS receiver.",
        "exif-coordinate-format": "{{optional}}\nFor formatting GPS latitude coordinates. Parameters:\n* $1 - degrees\n* $2 - minutes\n* $3 - seconds (up to two decimal places)\n* $4 - direction (N, S, W, or E)\n* $5 - (Unused) coordinate as a single positive or negative real number",
        "exif-jpegfilecomment": "This is not a true exif tag, but the contents of the JPEG COM segment. This often contains a file source, but can potentially contain any comment about the file. This is similar to {{msg-mw|exif-usercomment}}, {{msg-mw|exif-pngfilecomment}}, and {{msg-mw|exif-giffilecomment}}.",
-       "exif-keywords": "List of keywords for the photograph (or other media).\n\nThis can come from IPTC-iim 2:25 keyword field, or XMP's dc:subject field.\n{{Identical|Keyword}}",
+       "exif-keywords": "{{exif-qqq}}\n\nList of keywords for the photograph (or other media). This can come from IPTC-iim 2:25 keyword field, or XMP's dc:subject field.\n\n{{Identical|Keyword}}",
        "exif-worldregioncreated": "The world region (generally that means continent, but could also include 'World' as a whole) where the media was created.",
-       "exif-countrycreated": "Country that the picture was taken in. Note this is where it was taken, not what country is depicted in the picture.",
+       "exif-countrycreated": "{{exif-qqq}}\n\nCountry that the picture was taken in. Note this is where it was taken, not what country is depicted in the picture.",
        "exif-countrycodecreated": "ISO Code for the country that the picture was taken in. Note this is where it was taken, not what country is depicted in the picture.",
        "exif-provinceorstatecreated": "Province, state, territory, or other secondary political division (bigger than a city, smaller then a country) where that the picture was taken in.  Note this is where it was taken, not what province/state is depicted in the picture.",
        "exif-citycreated": "City that the picture was taken in.  Note this is where it was taken, not what city is depicted in the picture. This is generally only used if different from the city depicted in photo.",
        "exif-provinceorstatedest": "Province, state, territory, or other secondary political division shown.",
        "exif-citydest": "City shown",
        "exif-sublocationdest": "Sub-location of city shown. This could be an address, a street, an area of town, etc.",
-       "exif-objectname": "This is a short name for the image or other media. (As compared to {{msg-mw|exif-imagedescription}} which is a long description of the image).\n\nThis is sometimes an ID number used to identify the photo, or a (short) title of the photo.\n\nThis property is extracted based on XMP's dc:title property ( http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf ), PNG's title keyword ( http://www.w3.org/TR/PNG/#11keywords ), or IPTC-iim 2:05 Object name property ( http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf ).",
+       "exif-objectname": "{{exif-qqq}}\n\nThis is a short name for the image or other media. (As compared to {{msg-mw|exif-imagedescription}} which is a long description of the image).\n\nThis is sometimes an ID number used to identify the photo, or a (short) title of the photo.\n\nThis property is extracted based on XMP's [http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf dc:title property], PNG's [http://www.w3.org/TR/PNG/#11keywords title keyword], or IPTC-iim 2:05 [http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf Object name property].",
        "exif-specialinstructions": "Special instructions for how to use the image/media. This might include embargo notices, or other warnings.\n\nThis is IPTC-iim property 2:40. See http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf for details.",
-       "exif-headline": "A short version of the image caption. The IPTC4XMP standard is clear that \"this is not the same thing as title [ {{msg-mw|exif-objectname}} ]\".\n\nThis is extracted from XMP's photoshop:headline ( http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata-201007_1.pdf ) and IPTC-iim: 2:105 Headline tag ( http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf ).\n{{Identical|Headline}}",
+       "exif-headline": "{{exif-qqq}}\n\nA short version of the image caption. The IPTC4XMP standard is clear that \"this is not the same thing as title [ {{msg-mw|exif-objectname}} ]\".\n\nThis is extracted from [http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata-201007_1.pdf XMP's photoshop:headline] and [http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf IPTC-iim: 2:105 Headline tag].\n\n{{Identical|Headline}}",
        "exif-credit": "Provider/credit.\n\nWho gave us the image. This might be different from the creator of the image. This is IPTC-iim property 2:110",
-       "exif-source": "See IPTC-iim standard 2:115 - http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf.\n\nThis is who originally owned the image (a person, stock photo agency, etc). This does not refer to the image this image is based on.\n{{Identical|Source}}",
+       "exif-source": "{{exif-qqq}}\n\nSee [http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf IPTC-iim standard 2:115].\n\nThis is who originally owned the image (a person, stock photo agency, etc). This does not refer to the image this image is based on.\n\n{{Identical|Source}}",
        "exif-editstatus": "Editorial status of image. This is more intended for use with people making news papers. This denotes whether the image is on the main page, is part of a correction, etc. See 2:07 of http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf",
-       "exif-urgency": "Urgency. How urgent this image is. 1 is very urgent, 5 is normal, 8 is  very low priority.\n{{Related|Exif-urgency}}",
+       "exif-urgency": "{{exif-qqq}}\n\nUrgency. How urgent this image is. 1 is very urgent, 5 is normal, 8 is  very low priority.\n\n{{Related|Exif-urgency}}",
        "exif-fixtureidentifier": "Fixture name. Identifies frequently occurring object data, for example a regular column in a news paper.",
        "exif-locationdest": "Full printable name of location.",
        "exif-locationdestcode": "Code of location depicted. Typically this is an ISO country code, but the IPTC-iim standard also defines other codes like XSP for outer space. See appendix D (and tag 2:100) of http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf",
        "exif-objectcycle": "Time of day that media is intended for. Either morning only, evening only, or all day. Typically only used for news related things that might only be broadcast at a specific time of day.\n\nSee also:\n* {{msg-mw|Exif-objectcycle-a}}\n* {{msg-mw|Exif-objectcycle-p}}\n* {{msg-mw|Exif-objectcycle-b}}",
        "exif-contact": "Contact information of the person responsible for the image.",
        "exif-writer": "The person who wrote the caption of the image. See Description Writer on page 18 of http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata-201007_1.pdf\n{{Identical|Writer}}",
-       "exif-languagecode": "Language of image/media.\n\nThis is taken from IPTC-iim 2:135 and XMP's dc:language.\n{{Identical|Language}}",
+       "exif-languagecode": "{{exif-qqq}}\n\nLanguage of image/media. This is taken from IPTC-iim 2:135 and XMP's dc:language.\n\n{{Identical|Language}}",
        "exif-iimversion": "IIM version number. Version of information interchange 2:xx records. 4 is current version. 2 is often seen as well. This is the value stored 2:00 field (Note, iptc-iim also stores a model version in 1:00. This version field displays the 2:00 record only)",
-       "exif-iimcategory": "Primary Category of image (or other media). Technically supposed to be limited to 3 characters, however that is not always followed. Some common 3 letter category abbreviations are expanded by mediawiki. Similar to {{msg-mw|exif-keywords}}.\n{{Identical|Category}}",
+       "exif-iimcategory": "{{exif-qqq}}\n\nPrimary Category of image (or other media). Technically supposed to be limited to 3 characters, however that is not always followed. Some common 3 letter category abbreviations are expanded by mediawiki. Similar to {{msg-mw|exif-keywords}}.\n\n{{Identical|Category}}",
        "exif-iimsupplementalcategory": "Supplemental categories. Like {{msg-mw|exif-iimcategory}} but for categories beyond the main one.",
-       "exif-datetimeexpires": "Date after which not to use the image (media). This is often used in news situations were certain things (like forecasts) should not be used after a specified date.",
-       "exif-datetimereleased": "Earliest date the image (media) can be used.\n\nSee 2:30 of http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf",
+       "exif-datetimeexpires": "{{exif-qqq}}\n\nDate after which not to use the image (media). This is often used in news situations were certain things (like forecasts) should not be used after a specified date.",
+       "exif-datetimereleased": "{{exif-qqq}}\n\nEarliest date the image (media) can be used.\n\nSee 2:30 of http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf",
        "exif-originaltransmissionref": "This is basically a job ID. This could help an individual keep track of for what reason the image was created.\n\nSee Job Id on page 19 of http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata-201007_1.pdf",
-       "exif-identifier": "A formal identifier for the image. Often this is a URL.\n{{Identical|Identifier}}",
+       "exif-identifier": "{{exif-qqq}}\nA formal identifier for the image. Often this is a URL.\n{{Identical|Identifier}}",
        "exif-lens": "Description of lens used. This is taken from aux:Lens XMP property. See http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart2.pdf",
        "exif-serialnumber": "Serial number of camera. See aux:SerialNumber in http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart2.pdf",
        "exif-cameraownername": "Who owns the camera.",
-       "exif-label": "Label given to the image for organizational purposes. This is very similar to {{msg-mw|exif-keywords}}. Label is more used by a person to organize their media, where keywords are used to describe the photo contents itself.\n\nThis property can come from xmp:Label in XMP ( http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf ) or the label textual chunk in PNG.\n{{Identical|Label}}",
-       "exif-datetimemetadata": "Date metadata was last modified. Typically this refers to XMP metadata.",
+       "exif-label": "{{exif-qqq}}\n\nLabel given to the image for organizational purposes. This is very similar to {{msg-mw|exif-keywords}}. Label is more used by a person to organize their media, where keywords are used to describe the photo contents itself.\n\nThis property can come from xmp:Label in XMP ( http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf ) or the label textual chunk in PNG.\n\n{{Identical|Label}}",
+       "exif-datetimemetadata": "{{exif-qqq}}\n\nDate metadata was last modified. Typically this refers to XMP metadata.",
        "exif-nickname": "Short informal name of image. See http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart2.pdf",
        "exif-rating": "This is a rating for how good the image is. The range is between 1 to 5 (5 highest), with an additional option of \"reject\".",
        "exif-rightscertificate": "URL of Rights management certificate. This comes from XMPRights:Certificate property. See http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf",
        "exif-copyrighted": "Copyright status. This is a true or false field showing either Copyrighted or Public Domain. It should be noted that Copyrighted includes freely-licensed works.",
-       "exif-copyrightowner": "Copyright owner. Can have more than one person or entity.",
+       "exif-copyrightowner": "{{exif-qqq}}\n\nCopyright owner. Can have more than one person or entity.",
        "exif-usageterms": "Terms under which you're allowed to use the image/media.",
-       "exif-webstatement": "URL detailing the copyright status of the image, and how you're allowed to use the image. Often this is a link to a creative commons license, however the creative commons people recommend using a page that generally contains specific information about the image, and recommend using {{msg-mw|exif-licenseurl}} for linking to the license. See http://wiki.creativecommons.org/XMP",
+       "exif-webstatement": "{{exif-qqq}}\n\nURL detailing the copyright status of the image, and how you're allowed to use the image. Often this is a link to a creative commons license, however the creative commons people recommend using a page that generally contains specific information about the image, and recommend using {{msg-mw|exif-licenseurl}} for linking to the license. See http://wiki.creativecommons.org/XMP",
        "exif-originaldocumentid": "A unique ID of the original document (image) that this document (image) is based on.",
-       "exif-licenseurl": "URL for copyright license. This is almost always a creative commons license since this information comes from the creative commons namespace of XMP (but could be a link to any type of license). See also {{msg-mw|exif-webstatement}}",
+       "exif-licenseurl": "{{exif-qqq}}\n\nURL for copyright license. This is almost always a creative commons license since this information comes from the creative commons namespace of XMP (but could be a link to any type of license). See also {{msg-mw|exif-webstatement}}",
        "exif-morepermissionsurl": "A URL where you can \"buy\" (or otherwise negotiate) to get more rights for the image.",
        "exif-attributionurl": "A URL that you're supposed to use when re-using the image.",
        "exif-preferredattributionname": "The preferred name to give credit to when re-using this image.",
-       "exif-pngfilecomment": "See also:\n* {{msg-mw|Exif-pngfilecomment}}\n* {{msg-mw|Exif-giffilecomment}}",
-       "exif-disclaimer": "Disclaimer for the image.\n{{Identical|Disclaimer}}",
+       "exif-pngfilecomment": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-pngfilecomment}}\n* {{msg-mw|Exif-giffilecomment}}",
+       "exif-disclaimer": "{{exif-qqq}}\n\nDisclaimer for the image.\n\n{{Identical|Disclaimer}}",
        "exif-contentwarning": "Content warning for the image. For example if the image/media contains violent, sexual or otherwise offensive content.\n\nThis comes from the png warning textual chunk. See http://www.w3.org/TR/PNG/#11keywords",
-       "exif-giffilecomment": "See also:\n* {{msg-mw|Exif-pngfilecomment}}\n* {{msg-mw|Exif-giffilecomment}}",
+       "exif-giffilecomment": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-pngfilecomment}}\n* {{msg-mw|Exif-giffilecomment}}",
        "exif-intellectualgenre": "The \"intellectual genre\" of the image/media item. This typically means the type of item it is, ignoring the actual content of the item. See http://cv.iptc.org/newscodes/genre/ for some examples of the types of values this field might have.",
        "exif-subjectnewscode": "A (or multiple) codes describing the content of the image/media. The code is an 8 digit number representing some sort of category. The code is hierarchical , with the first two digits being a broad category (this broad category is shown to the user. See {{msg-mw|exif-subjectnewscode-value}} for how the value this field labels is shown to user). See http://cv.iptc.org/newscodes/subjectcode for the full list of codes.",
        "exif-scenecode": "IPTC (numeric) scene code. Contains information on what type of scene it is (like panoramic scene, close-up, etc). See http://cv.iptc.org/newscodes/scene/",
        "exif-software-value": "{{notranslate}}\nParameters:\n* $1 - software name",
        "exif-software-version-value": "{{notranslate}}\nParameters:\n* $1 - software name\n* $2 - version number",
        "exif-contact-value": "{{optional}}\nParameters:\n* $1 - email\n* $2 - URL of website\n* $3 - street address\n* $4 - city\n* $5 - region\n* $6 - postal code\n* $7 - country\n* $8 - telephone number\nNote, not all fields are guaranteed to be present, some may be empty strings.",
-       "exif-subjectnewscode-value": "{{Optional}}\nParameters:\n* $1 - numeric IPTC subject news code (one of http://cv.iptc.org/newscodes/subjectcode )\n* $2 - one of 17 broad categories that the code falls into. For example any code starting with 15 has the contents of {{msg-mw|Exif-iimcategory-spo}} for $2.",
-       "exif-compression-1": "{{Related|Exif-compression}}",
+       "exif-subjectnewscode-value": "{{Optional}}\n\n{{exif-qqq}}\n\nParameters:\n* $1 - numeric IPTC subject news code (one of http://cv.iptc.org/newscodes/subjectcode )\n* $2 - one of 17 broad categories that the code falls into. For example any code starting with 15 has the contents of {{msg-mw|Exif-iimcategory-spo}} for $2.",
+       "exif-compression-1": "{{exif-qqq}}\n{{Related|Exif-compression}}",
        "exif-compression-2": "{{Related|Exif-compression}}",
        "exif-compression-3": "{{Related|Exif-compression}}",
        "exif-compression-4": "{{Related|Exif-compression}}",
        "exif-photometricinterpretation-10": "See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
        "exif-photometricinterpretation-32803": "Used mostly by DNG images. See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
        "exif-photometricinterpretation-34892": "Used mostly by DNG images. See http://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html",
-       "exif-unknowndate": "Used if the Exif date and time is \"<code>0000:00:00 00:00:00</code>\".\n\nRelated Exif attributes:\n* {{msg-mw|Exif-datetime}}\n* {{msg-mw|Exif-datetimeoriginal}}\n* {{msg-mw|Exif-datetimedigitized}}\n* {{msg-mw|Exif-datetimereleased}}\n* {{msg-mw|Exif-datetimeexpires}}\n* {{msg-mw|Exif-gpsdatestamp}}\n* {{msg-mw|Exif-dc-date}}\n* {{msg-mw|Exif-datetimemetadata}}",
+       "exif-unknowndate": "{{exif-qqq}}\n\nUsed if the Exif date and time is \"<code>0000:00:00 00:00:00</code>\".\n\nRelated Exif attributes:\n* {{msg-mw|Exif-datetime}}\n* {{msg-mw|Exif-datetimeoriginal}}\n* {{msg-mw|Exif-datetimedigitized}}\n* {{msg-mw|Exif-datetimereleased}}\n* {{msg-mw|Exif-datetimeexpires}}\n* {{msg-mw|Exif-gpsdatestamp}}\n* {{msg-mw|Exif-dc-date}}\n* {{msg-mw|Exif-datetimemetadata}}",
        "exif-orientation-1": "0th row: top; 0th column: left\n{{Related|Exif-orientation}}\n{{Identical|Normal}}",
-       "exif-orientation-2": "0th row: top; 0th column: right\n{{Related|Exif-orientation}}",
-       "exif-orientation-3": "0th row: bottom; 0th column: right\n{{Related|Exif-orientation}}",
-       "exif-orientation-4": "0th row: bottom; 0th column: left\n{{Related|Exif-orientation}}",
+       "exif-orientation-2": "{{exif-qqq}}\n\n0th row: top; 0th column: right\n\n{{Related|Exif-orientation}}",
+       "exif-orientation-3": "{{exif-qqq}}\n\n0th row: bottom; 0th column: right\n\n{{Related|Exif-orientation}}",
+       "exif-orientation-4": "{{exif-qqq}}\n\n0th row: bottom; 0th column: left\n\n{{Related|Exif-orientation}}",
        "exif-orientation-5": "0th row: left; 0th column: top\n\nCCW is an abbreviation for counter-clockwise\n{{Related|Exif-orientation}}",
-       "exif-orientation-6": "0th row: right; 0th column: top\n\nCCW is an abbreviation for counter-clockwise.\n{{Related|Exif-orientation}}",
+       "exif-orientation-6": "{{exif-qqq}}\n\n0th row: right; 0th column: top\n\nCCW is an abbreviation for counter-clockwise.\n\n{{Related|Exif-orientation}}",
        "exif-orientation-7": "0th row: right; 0th column: bottom\n\nCW is an abbreviation for clockwise\n{{Related|Exif-orientation}}",
-       "exif-orientation-8": "0th row: left; 0th column: bottom\n\nCW is an abbreviation for clockwise.\n{{Related|Exif-orientation}}",
-       "exif-planarconfiguration-1": "See also:\n* {{msg-mw|Exif-planarconfiguration}}\n* {{msg-mw|Exif-planarconfiguration-1}}\n* {{msg-mw|Exif-planarconfiguration-2}}",
-       "exif-planarconfiguration-2": "See also:\n* {{msg-mw|Exif-planarconfiguration}}\n* {{msg-mw|Exif-planarconfiguration-1}}\n* {{msg-mw|Exif-planarconfiguration-2}}",
+       "exif-orientation-8": "{{exif-qqq}}\n\n0th row: left; 0th column: bottom\n\nCW is an abbreviation for clockwise.\n\n{{Related|Exif-orientation}}",
+       "exif-planarconfiguration-1": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-planarconfiguration}}\n* {{msg-mw|Exif-planarconfiguration-1}}\n* {{msg-mw|Exif-planarconfiguration-2}}",
+       "exif-planarconfiguration-2": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-planarconfiguration}}\n* {{msg-mw|Exif-planarconfiguration-1}}\n* {{msg-mw|Exif-planarconfiguration-2}}",
        "exif-xyresolution-i": "{{Optional}}\nUsed to format {{msg-mw|Exif-xresolution}} and {{msg-mw|Exif-yresolution}} if the unit is dots per inch.\n\nParameters:\n* $1 - the number of dots/in",
        "exif-xyresolution-c": "{{Optional}}\nUsed to format {{msg-mw|Exif-xresolution}} and {{msg-mw|Exif-yresolution}} if the unit is dots per centimeter.\n\nParameters:\n* $1 - the number of dots/cm",
-       "exif-colorspace-1": "{{Optional}}\nIf it uses the standard sRGB colour space.\n\nSee also:\n* {{msg-mw|Exif-colorspace}}\n* {{msg-mw|Exif-colorspace-1|optional}}\n* {{msg-mw|Exif-colorspace-65535}}",
-       "exif-colorspace-65535": "The photograph is not colour calibrated.\n\nSee also:\n* {{msg-mw|Exif-colorspace}}\n* {{msg-mw|Exif-colorspace-1|optional}}\n* {{msg-mw|Exif-colorspace-65535}}",
-       "exif-componentsconfiguration-0": "{{Related|Exif-componentsconfiguration}}",
-       "exif-componentsconfiguration-1": "{{optional}}\n{{Related|Exif-componentsconfiguration}}",
-       "exif-componentsconfiguration-2": "{{optional}}\n{{Related|Exif-componentsconfiguration}}",
-       "exif-componentsconfiguration-3": "{{optional}}\n{{Related|Exif-componentsconfiguration}}",
-       "exif-componentsconfiguration-4": "{{optional}}\n{{Related|Exif-componentsconfiguration}}",
-       "exif-componentsconfiguration-5": "{{optional}}\n{{Related|Exif-componentsconfiguration}}",
-       "exif-componentsconfiguration-6": "{{optional}}\n{{Related|Exif-componentsconfiguration}}",
-       "exif-exposureprogram-0": "{{Related|Exif-exposureprogram}}",
+       "exif-colorspace-1": "{{Optional}}\n{{exif-qqq}}\n\nThis value indicates that the image uses the standard sRGB colour space.\n\nSee also:\n* {{msg-mw|Exif-colorspace}}\n* {{msg-mw|Exif-colorspace-1|optional}}\n* {{msg-mw|Exif-colorspace-65535}}",
+       "exif-colorspace-65535": "{{exif-qqq}}\n\nThis value indicates that the photograph is not colour-calibrated.\n\nSee also:\n* {{msg-mw|Exif-colorspace}}\n* {{msg-mw|Exif-colorspace-1|optional}}\n* {{msg-mw|Exif-colorspace-65535}}",
+       "exif-componentsconfiguration-0": "{{exif-qqq}}\n{{Related|Exif-componentsconfiguration}}",
+       "exif-componentsconfiguration-1": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-componentsconfiguration}}",
+       "exif-componentsconfiguration-2": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-componentsconfiguration}}",
+       "exif-componentsconfiguration-3": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-componentsconfiguration}}",
+       "exif-componentsconfiguration-4": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-componentsconfiguration}}",
+       "exif-componentsconfiguration-5": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-componentsconfiguration}}",
+       "exif-componentsconfiguration-6": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-componentsconfiguration}}",
+       "exif-exposureprogram-0": "{{exif-qqq}}\n{{Related|Exif-exposureprogram}}",
        "exif-exposureprogram-1": "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.\n{{Related|Exif-exposureprogram}}\n{{Identical|Manual}}",
-       "exif-exposureprogram-2": "One of the exposure program types in the table of metadata on image description pages.\n{{Related|Exif-exposureprogram}}",
-       "exif-exposureprogram-3": "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article for a definition of the term [[w:Aperture_priority|aperture priority]].\n{{Related|Exif-exposureprogram}}",
-       "exif-exposureprogram-4": "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article for a definition of the term [[w:Shutter_priority|shutter priority]].\n{{Related|Exif-exposureprogram}}",
+       "exif-exposureprogram-2": "{{exif-qqq}}\n\nOne of the exposure program types in the table of metadata on image description pages.\n\n{{Related|Exif-exposureprogram}}",
+       "exif-exposureprogram-3": "{{exif-qqq}}\n\nOne of the exposure program types in the table of metadata on image description pages. See the Wikipedia article for a definition of the term [[w:Aperture_priority|aperture priority]].\n\n{{Related|Exif-exposureprogram}}",
+       "exif-exposureprogram-4": "{{exif-qqq}}\n\nOne of the exposure program types in the table of metadata on image description pages. See the Wikipedia article for a definition of the term [[w:Shutter_priority|shutter priority]].\n\n{{Related|Exif-exposureprogram}}",
        "exif-exposureprogram-5": "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.\n{{Related|Exif-exposureprogram}}",
        "exif-exposureprogram-6": "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.\n{{Related|Exif-exposureprogram}}",
        "exif-exposureprogram-7": "One of the exposure program types in the table of metadata on image description pages. See the Wikipedia article '[[w:Mode_dial|Mode dial]]' for an explanation.\n{{Related|Exif-exposureprogram}}",
        "exif-subjectdistance-value": "Parameters:\n* $1 - a distance measured in meters. The value can, and usually does, include decimal places.",
        "exif-meteringmode-0": "{{Related|Exif-meteringmode}}\n{{Identical|Unknown}}",
        "exif-meteringmode-1": "{{Related|Exif-meteringmode}}\n{{Identical|Average}}",
-       "exif-meteringmode-2": "{{Related|Exif-meteringmode}}",
-       "exif-meteringmode-3": "{{Related|Exif-meteringmode}}",
-       "exif-meteringmode-4": "{{Related|Exif-meteringmode}}",
-       "exif-meteringmode-5": "{{Related|Exif-meteringmode}}\n{{Identical|Pattern}}",
-       "exif-meteringmode-6": "{{Related|Exif-meteringmode}}",
+       "exif-meteringmode-2": "{{exif-qqq}}\n{{Related|Exif-meteringmode}}",
+       "exif-meteringmode-3": "{{exif-qqq}}\n{{Related|Exif-meteringmode}}",
+       "exif-meteringmode-4": "{{exif-qqq}}\n{{Related|Exif-meteringmode}}",
+       "exif-meteringmode-5": "{{exif-qqq}}\n{{Related|Exif-meteringmode}}\n{{Identical|Pattern}}",
+       "exif-meteringmode-6": "{{exif-qqq}}\n{{Related|Exif-meteringmode}}",
        "exif-meteringmode-255": "{{Identical|Other}}",
        "exif-lightsource-0": "{{Identical|Unknown}}\n{{Related|Exif-lightsource}}",
-       "exif-lightsource-1": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-2": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-3": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-4": "{{Identical|Flash}}\n{{Related|Exif-lightsource}}",
-       "exif-lightsource-9": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-10": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-11": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-12": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-13": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-14": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-15": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-17": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-18": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-19": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-20": "{{optional}}\n{{Related|Exif-lightsource}}",
-       "exif-lightsource-21": "{{optional}}\n{{Related|Exif-lightsource}}",
-       "exif-lightsource-22": "{{optional}}\n{{Related|Exif-lightsource}}",
-       "exif-lightsource-23": "{{optional}}\n{{Related|Exif-lightsource}}",
-       "exif-lightsource-24": "{{Related|Exif-lightsource}}",
-       "exif-lightsource-255": "{{Related|Exif-lightsource}}",
+       "exif-lightsource-1": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-2": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-3": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-4": "{{exif-qqq}}\n{{Identical|Flash}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-9": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-10": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-11": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-12": "{{exif-qqq}}\n\nThe \"D\" stands for \"daylight\", as defined in the JIS Z 9112:2012 standard.\n\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-13": "{{exif-qqq}}\n\nThe \"N\" symbol is defined in the JIS Z 9112:2012 standard.\n\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-14": "{{exif-qqq}}\n\nThe \"W\" stands for \"white\", as defined in the JIS Z 9112:2012 standard.\n\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-15": "{{exif-qqq}}\n\nThe \"WW\" stands for \"warm white\", as defined in the JIS Z 9112:2012 standard.\n\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-17": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-18": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-19": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-20": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-21": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-22": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-23": "{{optional}}\n{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-24": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
+       "exif-lightsource-255": "{{exif-qqq}}\n{{Related|Exif-lightsource}}",
        "exif-flash-fired-0": "{{Related|Exif-flash}}",
        "exif-flash-fired-1": "{{Related|Exif-flash}}",
        "exif-flash-return-0": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n\n\"Strobe\" and \"flash\" mean the same here.\n{{Related|Exif-flash}}",
        "exif-flash-mode-3": "{{Related|Exif-flash}}",
        "exif-flash-function-1": "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].\n{{Related|Exif-flash}}",
        "exif-flash-redeye-1": "{{Related|Exif-flash}}",
-       "exif-focalplaneresolutionunit-2": "See also:\n* {{msg-mw|Exif-focalplaneresolutionunit}}",
+       "exif-focalplaneresolutionunit-2": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-focalplaneresolutionunit}}",
        "exif-sensingmethod-1": "{{Related|Exif-sensingmethod}}\n{{Identical|Undefined}}",
        "exif-sensingmethod-2": "{{Related|Exif-sensingmethod}}",
        "exif-sensingmethod-3": "{{Related|Exif-sensingmethod}}",
        "exif-sensingmethod-4": "{{Related|Exif-sensingmethod}}",
        "exif-sensingmethod-5": "''Color sequential'' means, that the three base colors are measured one after another (i.e. the sensor is first measuring red, than green, than blue).\n{{Related|Exif-sensingmethod}}",
-       "exif-sensingmethod-7": "{{Related|Exif-sensingmethod}}",
+       "exif-sensingmethod-7": "{{exif-qqq}}\n{{Related|Exif-sensingmethod}}",
        "exif-sensingmethod-8": "''Color sequential'' means, that the three base colors are measured one after another (i.e. the sensor is first measuring red, than green, than blue).\n{{Related|Exif-sensingmethod}}",
        "exif-filesource-3": "{{optional}}",
        "exif-scenetype-1": "See also:\n* {{msg-mw|Exif-scenetype}}\n* {{msg-mw|Exif-scenetype-1}}",
-       "exif-customrendered-0": "See also:\n* {{msg-mw|Exif-customrendered}}\n* {{msg-mw|Exif-customrendered-0}}\n* {{msg-mw|Exif-customrendered-1}}",
-       "exif-customrendered-1": "See also:\n* {{msg-mw|Exif-customrendered}}\n* {{msg-mw|Exif-customrendered-0}}\n* {{msg-mw|Exif-customrendered-1}}",
-       "exif-exposuremode-0": "{{Related|Exif-exposuremode}}",
-       "exif-exposuremode-1": "{{Related|Exif-exposuremode}}",
-       "exif-exposuremode-2": "A type of exposure mode shown as part of the metadata on image description pages. The Wikipedia article on [[w:Bracketing#Exposure_bracketing|bracketing]] says that 'auto bracket' is a camera exposure setting which automatically takes a series of pictures at slightly different light exposures.\n{{Related|Exif-exposuremode}}",
-       "exif-whitebalance-0": "See also:\n* {{msg-mw|Exif-whitebalance}}\n* {{msg-mw|Exif-whitebalance-0}}\n* {{msg-mw|Exif-whitebalance-1}}",
-       "exif-whitebalance-1": "See also:\n* {{msg-mw|Exif-whitebalance}}\n* {{msg-mw|Exif-whitebalance-0}}\n* {{msg-mw|Exif-whitebalance-1}}",
+       "exif-customrendered-0": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-customrendered}}\n* {{msg-mw|Exif-customrendered-0}}\n* {{msg-mw|Exif-customrendered-1}}",
+       "exif-customrendered-1": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-customrendered}}\n* {{msg-mw|Exif-customrendered-0}}\n* {{msg-mw|Exif-customrendered-1}}",
+       "exif-exposuremode-0": "{{exif-qqq}}\n{{Related|Exif-exposuremode}}",
+       "exif-exposuremode-1": "{{exif-qqq}}\n{{Related|Exif-exposuremode}}",
+       "exif-exposuremode-2": "{{exif-qqq}}\n\nA type of exposure mode shown as part of the metadata on image description pages. The Wikipedia article on [[w:Bracketing#Exposure_bracketing|bracketing]] says that 'auto bracket' is a camera exposure setting which automatically takes a series of pictures at slightly different light exposures.\n\n{{Related|Exif-exposuremode}}",
+       "exif-whitebalance-0": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-whitebalance}}\n* {{msg-mw|Exif-whitebalance-0}}\n* {{msg-mw|Exif-whitebalance-1}}",
+       "exif-whitebalance-1": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-whitebalance}}\n* {{msg-mw|Exif-whitebalance-0}}\n* {{msg-mw|Exif-whitebalance-1}}",
        "exif-scenecapturetype-0": "{{Related|Exif-scenecapturetype}}\n{{Identical|Standard}}",
-       "exif-scenecapturetype-1": "{{Related|Exif-scenecapturetype}}",
-       "exif-scenecapturetype-2": "{{Related|Exif-scenecapturetype}}",
-       "exif-scenecapturetype-3": "{{Related|Exif-scenecapturetype}}",
+       "exif-scenecapturetype-1": "{{exif-qqq}}\n{{Related|Exif-scenecapturetype}}",
+       "exif-scenecapturetype-2": "{{exif-qqq}}\n{{Related|Exif-scenecapturetype}}",
+       "exif-scenecapturetype-3": "{{exif-qqq}}\n{{Related|Exif-scenecapturetype}}",
        "exif-gaincontrol-0": "Gain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n{{Related|Exif-gaincontrol}}\n{{Identical|None}}",
-       "exif-gaincontrol-1": "Gain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n{{Related|Exif-gaincontrol}}",
-       "exif-gaincontrol-2": "Gain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n{{Related|Exif-gaincontrol}}",
-       "exif-gaincontrol-3": "Gain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n{{Related|Exif-gaincontrol}}",
-       "exif-gaincontrol-4": "Gain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n{{Related|Exif-gaincontrol}}",
+       "exif-gaincontrol-1": "{{exif-qqq}}\n\nGain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n\n{{Related|Exif-gaincontrol}}",
+       "exif-gaincontrol-2": "{{exif-qqq}}\n\nGain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n\n{{Related|Exif-gaincontrol}}",
+       "exif-gaincontrol-3": "{{exif-qqq}}\n\nGain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n\n{{Related|Exif-gaincontrol}}",
+       "exif-gaincontrol-4": "{{exif-qqq}}\n\nGain amplifies the signal off of the image sensor. Gain turns the brightness level up or down.\n\n{{Related|Exif-gaincontrol}}",
        "exif-contrast-0": "{{Related|Exif-contrast}}\n{{Identical|Normal}}",
-       "exif-contrast-1": "{{Related|Exif-contrast}}\n{{Identical|Soft}}",
-       "exif-contrast-2": "{{Related|Exif-contrast}}\n{{Identical|Hard}}",
+       "exif-contrast-1": "{{exif-qqq}}\n{{Related|Exif-contrast}}\n{{Identical|Soft}}",
+       "exif-contrast-2": "{{exif-qqq}}\n{{Related|Exif-contrast}}\n{{Identical|Hard}}",
        "exif-saturation-0": "{{Related|Exif-saturation}}\n{{Identical|Normal}}",
-       "exif-saturation-1": "{{Related|Exif-saturation}}",
-       "exif-saturation-2": "Color saturation in picture EXIF data\n{{Related|Exif-saturation}}",
+       "exif-saturation-1": "{{exif-qqq}}\n{{Related|Exif-saturation}}",
+       "exif-saturation-2": "{{exif-qqq}}\n\nColor saturation in picture EXIF data\n\n{{Related|Exif-saturation}}",
        "exif-sharpness-0": "{{Related|Exif-sharpness}}\n{{Identical|Normal}}",
-       "exif-sharpness-1": "{{Related|Exif-sharpness}}\n{{Identical|Soft}}",
-       "exif-sharpness-2": "{{Related|Exif-sharpness}}\n{{Identical|Hard}}",
+       "exif-sharpness-1": "{{exif-qqq}}\n{{Related|Exif-sharpness}}\n{{Identical|Soft}}",
+       "exif-sharpness-2": "{{exif-qqq}}\n{{Related|Exif-sharpness}}\n{{Identical|Hard}}",
        "exif-subjectdistancerange-0": "{{Related|Exif-subjectdistancerange}}\n{{Identical|Unknown}}",
-       "exif-subjectdistancerange-1": "Macro view is close-up photography. See [[w:Macro_photography|Wikipedia]].\n{{Identical|Macro}}\n{{Related|Exif-subjectdistancerange}}",
-       "exif-subjectdistancerange-2": "{{Related|Exif-subjectdistancerange}}",
-       "exif-subjectdistancerange-3": "{{Related|Exif-subjectdistancerange}}",
-       "exif-gpslatitude-n": "Very rarely used. Only used when using an old version of Mediawiki as a foreign image repo.\n{{Related|Exif-gpslatitude}}",
-       "exif-gpslatitude-s": "Very rarely used. Only used when using an old version of Mediawiki as a foreign image repo.\n{{Related|Exif-gpslatitude}}",
-       "exif-gpslongitude-e": "Very rarely used. Only used when using an old version of Mediawiki as a foreign image repo.\n{{Related|Exif-gpslatitude}}",
-       "exif-gpslongitude-w": "Very rarely used. Only used when using an old version of Mediawiki as a foreign image repo.\n{{Related|Exif-gpslatitude}}",
+       "exif-subjectdistancerange-1": "{{exif-qqq}}\n\nMacro view is close-up photography. See [[w:Macro photography|Wikipedia]].\n\n{{Identical|Macro}}\n{{Related|Exif-subjectdistancerange}}",
+       "exif-subjectdistancerange-2": "{{exif-qqq}}\n{{Related|Exif-subjectdistancerange}}",
+       "exif-subjectdistancerange-3": "{{exif-qqq}}\n{{Related|Exif-subjectdistancerange}}",
+       "exif-gpslatitude-n": "{{exif-qqq}}\n\nVery rarely used. Only used when using an old version of Mediawiki as a foreign image repo.\n\n{{Related|Exif-gpslatitude}}",
+       "exif-gpslatitude-s": "{{exif-qqq}}\n\nVery rarely used. Only used when using an old version of Mediawiki as a foreign image repo.\n\n{{Related|Exif-gpslatitude}}",
+       "exif-gpslongitude-e": "{{exif-qqq}}\n\nVery rarely used. Only used when using an old version of Mediawiki as a foreign image repo.\n\n{{Related|Exif-gpslatitude}}",
+       "exif-gpslongitude-w": "{{exif-qqq}}\n\nVery rarely used. Only used when using an old version of Mediawiki as a foreign image repo.\n\n{{Related|Exif-gpslatitude}}",
        "exif-gpsaltitude-above-sealevel": "Used as GPS Altitude in Exif data. Parameters:\n* $1 - altitude above sea level (in meters)\nSee also:\n* {{msg-mw|Exif-gpsaltitude-below-sealevel}}",
        "exif-gpsaltitude-below-sealevel": "Used as GPS Altitude in Exif data. Parameters:\n* $1 - altitude below sea level (in meters)\nSee also:\n* {{msg-mw|Exif-gpsaltitude-above-sealevel}}",
-       "exif-gpsstatus-a": "See also:\n* {{msg-mw|Exif-gpsstatus}}\n* {{msg-mw|Exif-gpsstatus-v}}",
-       "exif-gpsstatus-v": "See also:\n* {{msg-mw|Exif-gpsstatus}}\n* {{msg-mw|Exif-gpsstatus-a}}",
-       "exif-gpsmeasuremode-2": "Only latitude and longitude recorded, no altitude.\n\nSee also:\n* {{msg-mw|Exif-gpsmeasuremode}}\n* {{msg-mw|Exif-gpsmeasuremode-3}}",
-       "exif-gpsmeasuremode-3": "Latitude, longitude, and altitude recorded.\n\nSee also:\n* {{msg-mw|Exif-gpsmeasuremode}}\n* {{msg-mw|Exif-gpsmeasuremode-2}}",
-       "exif-gpsspeed-k": "{{Related|Exif-gpsspeed}}",
-       "exif-gpsspeed-m": "{{Related|Exif-gpsspeed}}",
-       "exif-gpsspeed-n": "Knots: ''Knot'' is a unit of speed on water used for ships, etc., equal to one nautical mile per hour.\n{{Related|Exif-gpsspeed}}",
-       "exif-gpsdestdistance-k": "{{Related|Exif-gpsdestdistance}}",
-       "exif-gpsdestdistance-m": "{{Related|Exif-gpsdestdistance}}",
-       "exif-gpsdestdistance-n": "{{Related|Exif-gpsdestdistance}}",
+       "exif-gpsstatus-a": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpsstatus}}\n* {{msg-mw|Exif-gpsstatus-v}}",
+       "exif-gpsstatus-v": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpsstatus}}\n* {{msg-mw|Exif-gpsstatus-a}}",
+       "exif-gpsmeasuremode-2": "{{exif-qqq}}\n\nOnly latitude and longitude recorded, no altitude.\n\nSee also:\n* {{msg-mw|Exif-gpsmeasuremode}}\n* {{msg-mw|Exif-gpsmeasuremode-3}}",
+       "exif-gpsmeasuremode-3": "{{exif-qqq}}\n\nLatitude, longitude, and altitude recorded.\n\nSee also:\n* {{msg-mw|Exif-gpsmeasuremode}}\n* {{msg-mw|Exif-gpsmeasuremode-2}}",
+       "exif-gpsspeed-k": "{{exif-qqq}}\n{{Related|Exif-gpsspeed}}",
+       "exif-gpsspeed-m": "{{exif-qqq}}\n{{Related|Exif-gpsspeed}}",
+       "exif-gpsspeed-n": "{{exif-qqq}}\n\n''Knot'' is a unit of speed on water used for ships, etc., equal to one nautical mile per hour.\n\n{{Related|Exif-gpsspeed}}",
+       "exif-gpsdestdistance-k": "{{exif-qqq}}\n{{Related|Exif-gpsdestdistance}}",
+       "exif-gpsdestdistance-m": "{{exif-qqq}}\n{{Related|Exif-gpsdestdistance}}",
+       "exif-gpsdestdistance-n": "{{exif-qqq}}\n{{Related|Exif-gpsdestdistance}}",
        "exif-gpsdop-excellent": "Parameters:\n* $1 - the actual HDOP/PDOP value (less than or equal to 2 for excellent). See http://en.wikipedia.org/wiki/Dilution_of_precision_(GPS)\n{{Related|Exif-gpsdop}}",
        "exif-gpsdop-good": "Parameters:\n* $1 - the actual HDOP/PDOP value (2-5 for good). See http://en.wikipedia.org/wiki/Dilution_of_precision_(GPS)\n{{Related|Exif-gpsdop}}",
        "exif-gpsdop-moderate": "Parameters:\n* $1 - the actual HDOP/PDOP value (5-10 for moderate). See http://en.wikipedia.org/wiki/Dilution_of_precision_(GPS)\n{{Related|Exif-gpsdop}}\n{{Identical|Moderate}}",
-       "exif-gpsdop-fair": "Parameters:\n* $1 - the actual HDOP/PDOP value (10-20 for fair). See http://en.wikipedia.org/wiki/Dilution_of_precision_(GPS)\n{{Related|Exif-gpsdop}}",
+       "exif-gpsdop-fair": "{{exif-qqq}}\n\nParameters:\n* $1 - the actual HDOP/PDOP value (10-20 for fair). See http://en.wikipedia.org/wiki/Dilution_of_precision_(GPS)\n\n{{Related|Exif-gpsdop}}",
        "exif-gpsdop-poor": "Parameters:\n* $1 - the actual HDOP/PDOP value (greater than 20 for poor). See http://en.wikipedia.org/wiki/Dilution_of_precision_(GPS)\n{{Related|Exif-gpsdop}}",
        "exif-objectcycle-a": "Morning only (a is for AM).\n\nSee also:\n* {{msg-mw|Exif-objectcycle}}\n* {{msg-mw|Exif-objectcycle-p}}\n* {{msg-mw|Exif-objectcycle-b}}",
-       "exif-objectcycle-p": "Evening only (p is for PM).\n\nSee also:\n* {{msg-mw|Exif-objectcycle}}\n* {{msg-mw|Exif-objectcycle-a}}\n* {{msg-mw|Exif-objectcycle-b}}",
+       "exif-objectcycle-p": "{{exif-qqq}}\n\nEvening only (p is for PM).\n\nSee also:\n* {{msg-mw|Exif-objectcycle}}\n* {{msg-mw|Exif-objectcycle-a}}\n* {{msg-mw|Exif-objectcycle-b}}",
        "exif-objectcycle-b": "Both morning and evening (b is for both).\n\nSee also:\n* {{msg-mw|Exif-objectcycle}}\n* {{msg-mw|Exif-objectcycle-a}}\n* {{msg-mw|Exif-objectcycle-p}}",
-       "exif-gpsdirection-t": "See also:\n* {{msg-mw|Exif-gpsdirection-m}}",
-       "exif-gpsdirection-m": "See also:\n* {{msg-mw|Exif-gpsdirection-t}}",
-       "exif-ycbcrpositioning-1": "If the Chrominance samples are centered with respect to the Luminance samples.\n{{Related|Exif-ycbcrpositioning}}",
+       "exif-gpsdirection-t": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpsdirection-m}}",
+       "exif-gpsdirection-m": "{{exif-qqq}}\n\nSee also:\n* {{msg-mw|Exif-gpsdirection-t}}",
+       "exif-ycbcrpositioning-1": "{{exif-qqq}}\n\nThis tag indicates that the Chrominance samples are centered with respect to the Luminance samples.\n\n{{Related|Exif-ycbcrpositioning}}",
        "exif-ycbcrpositioning-2": "If the Chrominance samples are on top of to the Luminance samples.\nSee: http://www.awaresystems.be/imaging/tiff/tifftags/ycbcrpositioning.html\n{{Related|Exif-ycbcrpositioning}}",
        "exif-dc-contributor": "People who helped make the resource, but are secondary in contribution to the author.\n{{Identical|Contributor}}",
        "exif-dc-coverage": "\"The extent or scope of the resource\" see dc:coverage in http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart2.pdf",
        "exif-iimcategory-evn": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}",
        "exif-iimcategory-hth": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}",
        "exif-iimcategory-hum": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}",
-       "exif-iimcategory-lab": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}\n\n\"Labor\" here refers to all news on labor issues; employment; unemployment; work relations; labor disputes; strikes; legislation; unions; job related issues; government policy. (at least, according to Reuters.)",
+       "exif-iimcategory-lab": "{{exif-qqq}}\n\nDisplayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}\n\n\"Labor\" here refers to all news on labor issues; employment; unemployment; work relations; labor disputes; strikes; legislation; unions; job related issues; government policy. (at least, according to Reuters.)",
        "exif-iimcategory-lif": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}",
        "exif-iimcategory-pol": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}",
        "exif-iimcategory-rel": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}",
        "exif-iimcategory-spo": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}.\n{{Identical|Sport}}",
        "exif-iimcategory-war": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}",
        "exif-iimcategory-wea": "Displayed as part of the iimcategory field if the 3 letter code is recognized, or as part {{msg-mw|exif-subjectnewscode-value}}",
-       "exif-urgency-normal": "Parameters:\n* $1 - numeric priority (aka 5 for normal)\n{{Related|Exif-urgency}}",
-       "exif-urgency-low": "Parameters:\n* $1 - numeric priority (6-8 for low)\n{{Related|Exif-urgency}}",
+       "exif-urgency-normal": "{{exif-qqq}}\n\nParameters:\n* $1 - numeric priority (aka 5 for normal)\n\n{{Related|Exif-urgency}}",
+       "exif-urgency-low": "{{exif-qqq}}\n\nParameters:\n* $1 - numeric priority (6-8 for low)\n\n{{Related|Exif-urgency}}",
        "exif-urgency-high": "Parameters:\n* $1 - numeric priority (1-4 for high)\n{{Related|Exif-urgency}}",
        "exif-urgency-other": "Parameters:\n* $1 - numeric priority. Most specs define 0 and 9 to either be reserved or not allowed. However the exiftool documentation defines 0 to be reserved and 9 to be user-defined priority.\n{{Related|Exif-urgency}}",
        "namespacesall": "In special page [[Special:WhatLinksHere]]. Drop-down box option for namespace.\n\n{{Identical|All}}",
        "mw-widgets-dateinput-placeholder-month": "Placeholder displayed in a date input field when it's empty, representing a date format with 4 digits for year and 2 digits for month, separated with hyphens (without a day). This should be uppercase, if possible, and must not include any additional explanations. If there is no good way to translate it, make this message blank.",
        "mw-widgets-titleinput-description-new-page": "Description label for a new page in the title input widget.",
        "mw-widgets-titleinput-description-redirect": "Description label for a redirect in the title input widget.",
-       "api-error-blacklisted": "Used as error message.\n\nFollowed by the link {{msg-mw|Mwe-upwiz-feedback-blacklist-info-prompt}}.",
        "sessionmanager-tie": "Used as an error message when multiple session sources are tied in priority.\n\nParameters:\n* $1 - List of dession type descriptions, from messages like {{msg-mw|sessionprovider-mediawiki-session-cookiesessionprovider}}.",
        "sessionprovider-generic": "Used to create a generic session type description when one isn't provided via the proper message. Should be phrased to make sense when added to a message such as {{msg-mw|cannotloginnow-text}}.\n\nParameters:\n* $1 - PHP classname.",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "Description of the sessions provided by the CookieSessionProvider class, which use HTTP cookies. Should be phrased to make sense when added to a message such as {{msg-mw|cannotloginnow-text}}.",
index 0321d19..3f7621d 100644 (file)
@@ -92,7 +92,8 @@
                        "Lemondoge",
                        "SamGold",
                        "Jdforrester",
-                       "Jack who built the house"
+                       "Jack who built the house",
+                       "Cat1987"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "poolcounter-usage-error": "Ошибка использования: $1",
        "aboutsite": "Описание {{grammar:genitive|{{SITENAME}}}}",
        "aboutpage": "Project:Описание",
-       "copyright": "СодеÑ\80жимое доступно по лицензии $1 (если не указано иное).",
+       "copyright": "СодеÑ\80жание доступно по лицензии $1 (если не указано иное).",
        "copyrightpage": "{{ns:project}}:Авторские права",
        "currentevents": "Текущие события",
        "currentevents-url": "Project:Текущие события",
        "passwordreset-emailsent-capture2": "{{PLURAL:$1|Письмо|Письма}} для сброса пароля {{PLURAL:$1|было отправлено|были отправлены}}. {{PLURAL:$1|Логин и пароль показаны|Список логинов и паролей показан}} ниже.",
        "passwordreset-emailerror-capture2": "Отправка {{GENDER:$2|участнику}} письма по электронной почте не удалась: $1 В {{PLURAL:$3|логин и пароль показаны|список логинов и паролей показан}} ниже.",
        "passwordreset-invalideamil": "Недопустимый адрес электронной почты",
+       "passwordreset-nodata": "Ни имя участника, ни адрес электронной почты не были предоставлены",
        "changeemail": "Изменить или удалить адрес электронной почты",
        "changeemail-header": "Заполните эту форму, чтобы изменить свой адрес электронной почты. Если вы хотите отвязать свой адрес электронной почты от учётной записи, то при заполнении формы оставьте пустым поле нового адреса электронной почты.",
        "changeemail-passwordrequired": "Чтобы подтвердить это изменение, вам нужно будет ввести свой пароль.",
        "summary": "Описание изменений:",
        "subject": "Тема/заголовок:",
        "minoredit": "Малое изменение",
-       "watchthis": "Ð\92клÑ\8eÑ\87иÑ\82Ñ\8c Ñ\8dÑ\82Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 Ð² Ñ\81пиÑ\81ок Ð½Ð°Ð±Ð»Ñ\8eдениÑ\8f",
+       "watchthis": "СледиÑ\82Ñ\8c Ð·Ð° Ñ\8dÑ\82ой Ñ\81Ñ\82Ñ\80аниÑ\86ей",
        "savearticle": "Записать страницу",
        "savechanges": "Сохранить изменения",
        "publishpage": "издавать страницу",
        "content-model-css": "CSS",
        "content-json-empty-object": "Пустой объект",
        "content-json-empty-array": "Пустой массив",
+       "deprecated-self-close-category": "Страницы, использующие недопустимые самозакрывающеся HTML-теги",
        "duplicate-args-warning": "<strong>Внимание:</strong> [[:$1]] вызывает [[:$2]] с более чем одним значением параметра «$3». Будет использовано только последнее указанное значение.",
        "duplicate-args-category": "Страницы, использующие повторяющиеся аргументы в вызовах шаблонов",
        "duplicate-args-category-desc": "Страницы, содержащие вызовы шаблонов, использующие повторяющиеся аргументы, такие как <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> или <code><nowiki>{{foo|bar|1=bar}}</nowiki></code>.",
        "searchall": "все",
        "showingresults": "Ниже {{PLURAL:$1|1=показан <strong>1</strong> результат|показан  <strong>$1</strong> результат|показано <strong>$1</strong> результата|показаны <strong>$1</strong> результатов}}, начиная с № <strong>$2</strong>.",
        "showingresultsinrange": "Ниже показано до {{PLURAL:$1|<strong>1</strong> результата|<strong>$1</strong> результата|<strong>$1</strong> результатов}} в диапазоне от <strong>$2</strong> до <strong>$3</strong>.",
-       "search-showingresults": "{{PLURAL:$4|Результат <strong>$1</strong> из <strong>$3</strong>|Результаты <strong>$1—$2</strong> из <strong>$3</strong>}}",
+       "search-showingresults": "{{PLURAL:$4|1=Результат <strong>$1</strong> из <strong>$3</strong>|Результаты <strong>$1—$2</strong> из <strong>$3</strong>}}",
        "search-nonefound": "Соответствий запросу не найдено.",
        "search-nonefound-thiswiki": "Нет результатов, соответствующих запросу на этом сайте.",
        "powersearch-legend": "Расширенный поиск",
        "trackingcategories-name": "Имя сообщения",
        "trackingcategories-desc": "Критерий включения в категорию",
        "restricted-displaytitle-ignored": "Страницы с игнорируемыми отображаемыми названиями",
+       "restricted-displaytitle-ignored-desc": "На странице есть игнорируемый <code><nowiki>{{DISPLAYTITLE}}</nowiki></code>, поскольку он не соответствует реальному названию страницы.",
        "noindex-category-desc": "Страница не индексируются поисковыми роботами, потому что на ней имеется «волшебное слово» <code><nowiki>__NOINDEX__</nowiki></code>, и она находится в пространстве имён, где разрешён этот флаг).",
        "index-category-desc": "На странице имеется «волшебное слово» <nowiki>__INDEX__</nowiki> (и страница находится в пространстве имён, где разрешён этот флаг), поэтому она индексируются поисковыми роботами в тех случаях, когда этого обычно не происходит.",
        "post-expand-template-inclusion-category-desc": "Размер страницы станет больше <code>$wgMaxArticleSize</code> после показа всех шаблонов, поэтому некоторые из них не были показаны полностью.",
        "addedwatchtext": "Страница «[[:$1]]» вместе с её обсуждением были добавлены в ваш [[Special:Watchlist|список наблюдения]].",
        "addedwatchtext-short": "Страница «$1» была добавлена в ваш список наблюдения.",
        "removewatch": "Удалить из списка наблюдения",
-       "removedwatchtext": "Статья «[[:$1]]» и её страница обсуждения были удалены из вашего [[Special:Watchlist|списка наблюдения]].",
+       "removedwatchtext": "Страница «[[:$1]]» вместе с её обсуждением были удалены из вашего [[Special:Watchlist|списка наблюдения]].",
        "removedwatchtext-short": "Страница «$1» была удалена из вашего списка наблюдения.",
        "watch": "Следить",
        "watchthispage": "Наблюдать за этой страницей",
        "notvisiblerev": "Версия была удалена",
        "watchlist-details": "В вашем списке наблюдения $1 {{PLURAL:$1|страница|страницы|страниц}}, не считая страниц обсуждений.",
        "wlheader-enotif": "Уведомления по эл. почте включены.",
-       "wlheader-showupdated": "Страницы, изменившиеся с вашего последнего их посещения, выделены '''жирным''' шрифтом.",
+       "wlheader-showupdated": "СÑ\82Ñ\80аниÑ\86Ñ\8b, Ð¸Ð·Ð¼ÐµÐ½Ð¸Ð²Ñ\88иеÑ\81Ñ\8f Ñ\81 Ð²Ð°Ñ\88его Ð¿Ð¾Ñ\81леднего Ð¸Ñ\85 Ð¿Ð¾Ñ\81еÑ\89ениÑ\8f, Ð²Ñ\8bделенÑ\8b '''полÑ\83жиÑ\80нÑ\8bм''' Ñ\88Ñ\80иÑ\84Ñ\82ом.",
        "wlnote": "Ниже {{PLURAL:$1|показано последнее изменение|показаны <strong>$1</strong> последние изменения|показаны <strong>$1</strong> последних изменений}} за {{PLURAL:$2|последний час|последние <strong>$2</strong> часа|последние <strong>$2</strong> часов}}, по состоянию на $3 $4.",
        "wlshowlast": "Показать за последние $1 часов $2 дней",
        "watchlist-hide": "Скрыть",
        "revertpage": "Откат правок [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]]) к версии [[User:$1|$1]]",
        "revertpage-nouser": "Правки (имя участника скрыто) откачены к версии {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Откачены правки $1; возврат к версии $2.",
+       "rollback-success-notify": "Откачены правки $1; возврат к последней версии $2. [$3 Показать изменения]",
        "sessionfailure-title": "Ошибка сеанса",
        "sessionfailure": "Похоже, возникли проблемы с текущим сеансом работы;\nэто действие было отменено в целях предотвращения «захвата сеанса».\nПожалуйста, нажмите кнопку «Назад» и перезагрузите страницу, с которой вы пришли.",
        "changecontentmodel": "Редактирование контентной модели страницы",
        "tooltip-ca-undelete": "Восстановить исправления страницы, сделанные до того, как она была удалена",
        "tooltip-ca-move": "Переименовать страницу",
        "tooltip-ca-watch": "Добавить эту страницу в ваш список наблюдения",
-       "tooltip-ca-unwatch": "Удалить эту страницу из вашего списка наблюдения",
+       "tooltip-ca-unwatch": "Удалить эту страницу из своего списка наблюдения",
        "tooltip-search": "Искать в {{grammar:prepositional|{{SITENAME}}}}",
        "tooltip-search-go": "Перейти к странице, имеющей в точности такое название",
        "tooltip-search-fulltext": "Найти страницы, содержащие указанный текст",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
        "mw-widgets-titleinput-description-new-page": "страница ещё не существует",
        "mw-widgets-titleinput-description-redirect": "перенаправление на $1",
-       "api-error-blacklisted": "Пожалуйста, выберите другое, более понятное название.",
        "sessionmanager-tie": "Невозможно использовать одновременно несколько типов проверки подлинности запроса: $1.",
        "sessionprovider-generic": "$1 сессий",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "сессий на основе куки",
        "log-action-filter-newusers": "Тип создания учётной записи:",
        "log-action-filter-patrol": "Тип патрулирования:",
        "log-action-filter-protect": "Тип защиты:",
-       "log-action-filter-rights": "Тип изменения прав",
-       "log-action-filter-suppress": "Тип сокрытия",
+       "log-action-filter-rights": "Тип изменения прав:",
+       "log-action-filter-suppress": "Тип сокрытия:",
        "log-action-filter-upload": "Тип загрузки:",
        "log-action-filter-all": "Все",
        "log-action-filter-block-block": "Блокировка",
        "log-action-filter-suppress-reblock": "Сокрытие пользователя через повторное блокирование",
        "log-action-filter-upload-upload": "Новая загрузка",
        "log-action-filter-upload-overwrite": "Повторно загрузить",
+       "authmanager-authn-no-primary": "Предоставленные учётные данные не могут быть проверены на подлинность.",
+       "authmanager-authn-no-local-user": "Предоставленные учётные данные не связаны ни с одним участником этой вики.",
+       "authmanager-authn-no-local-user-link": "Предоставленные учётные данные корректны, но не связаны ни с одни участником этой вики. Войдите с помощью какого-то другого способа или создайте новую учётную запись, и у вас появится возможность привязать свои предыдущие учётные данные к этой учетной записи.",
        "authmanager-authn-autocreate-failed": "Автоматическое создание локальной учётной записи не удалось: $1",
        "authmanager-create-disabled": "Создание учётных записей отключено.",
        "authmanager-create-from-login": "Чтобы создать учётную запись, пожалуйста, заполните приведённые ниже поля.",
+       "authmanager-create-not-in-progress": "Создание учётной записи не выполняется или данные сессии были утеряны. Пожалуйста, начните снова с самого начала.",
+       "authmanager-create-no-primary": "Предоставленные учётные данные не могут быть использованы для создания учётной записи.",
+       "authmanager-link-no-primary": "Предоставленные учётные данные не могут быть использованы для связывания учётных записей.",
+       "authmanager-link-not-in-progress": "Связывание учётной записи не выполняется или данные сессии были утеряны. Пожалуйста, начните снова с самого начала.",
        "authmanager-authplugin-setpass-failed-title": "Ошибка изменения пароля",
        "authmanager-authplugin-setpass-failed-message": "Плагин аутентификации запрещает смену пароля.",
        "authmanager-authplugin-create-fail": "Плагин аутентификации запрещает создание учётных записей.",
+       "authmanager-authplugin-setpass-denied": "Плагин аутентификации не позволяет изменять пароли.",
        "authmanager-authplugin-setpass-bad-domain": "Неверный домен.",
        "authmanager-autocreate-noperm": "Автоматическое создание учётных записей не разрешено.",
        "authmanager-autocreate-exception": "Автоматическое создание учётной записи временно отключено из-за предыдущих ошибок.",
        "authmanager-realname-label": "Настоящее имя",
        "authmanager-realname-help": "Настоящее имя участника",
        "authmanager-provider-password": "Аутентификация на основе пароля",
+       "authmanager-provider-password-domain": "Проверка подлинности на основе пароля и домена",
        "authmanager-provider-temporarypassword": "Временный пароль",
        "authprovider-confirmlink-option": "$1 ($2)",
        "authprovider-confirmlink-request-label": "Учётные записи, которые должны быть связаны",
        "authprovider-confirmlink-ok-help": "Продолжать после вывода сообщений об ошибках связывания.",
        "authprovider-resetpass-skip-label": "Пропустить",
        "authprovider-resetpass-skip-help": "Пропустить сброс пароля.",
+       "authform-nosession-signup": "Учётная запись была создана, но ваш браузер не сможет «запомнить», что вы вошли.\n\n$1",
        "authform-newtoken": "Отсутствует токен. $1",
        "authform-notoken": "Отсутствует токен",
        "authform-wrongtoken": "Неверный токен",
index 84af377..3c18dc9 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Prazen objekt",
        "content-json-empty-array": "Prazno polje",
+       "deprecated-self-close-category": "Strani, ki uporabljajo neveljavne samozaključljive oznake HTML",
+       "deprecated-self-close-category-desc": "Stran uporablja neveljavne samozaključljive oznake HTML, kot sta <code>&lt;b/></code> ali <code>&lt;span/></code>. Njihovo vedenje se bo kmalu spremenilo, da bo v skladu s specifikacijo HTML5, zato njihova uporaba v wikibesedilu ni zaželena.",
        "duplicate-args-warning": "<strong>Opozorilo:</strong> [[:$1]] kliče [[:$2]] z več kot eno vrednostjo za parameter »$3«. Uporabili bomo samo zadnjo navedeno vrednost.",
        "duplicate-args-category": "Strani s podvojenimi argumenti v klicih predlog",
        "duplicate-args-category-desc": "Stran vsebuje klice predlog, ki vsebujejo dvojnike argumentov, kot sta <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ali <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "LLLL-MM",
        "mw-widgets-titleinput-description-new-page": "stran še ne obstaja",
        "mw-widgets-titleinput-description-redirect": "preusmeritev na $1",
-       "api-error-blacklisted": "Prosimo, izberite drugačen, opisen naslov.",
        "sessionmanager-tie": "Ne morem združiti več vrst overitvenih zahtev: $1.",
        "sessionprovider-generic": "sej $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sej, ki temeljijo na piškotkih",
        "log-action-filter-newusers": "Vrsta ustvarjanja računa:",
        "log-action-filter-patrol": "Vrsta nadzora:",
        "log-action-filter-protect": "Vrsta zaščite:",
-       "log-action-filter-rights": "Vrsta spremembe pravic",
-       "log-action-filter-suppress": "Vrsta zatrtja",
+       "log-action-filter-rights": "Vrsta spremembe pravic:",
+       "log-action-filter-suppress": "Vrsta zatrtja:",
        "log-action-filter-upload": "Vrsta nalaganja:",
        "log-action-filter-all": "Vse",
        "log-action-filter-block-block": "Blokada",
index 0601177..7c78a48 100644 (file)
        "passwordreset-emailtext-ip": "Неко (вероватно Ви, са ИП адресе $1) је затражио нову лозинку на викију {{SITENAME}} ($4).\nСледећи {{PLURAL:$3|кориснички налог је повезан|кориснички налози су повезани}} с овом имејл адресом:\n\n$2\n\n{{PLURAL:$3|Привремена лозинка истиче|Привремене лозинке истичу}} за {{PLURAL:$5|један дан|$5 дана}}.\nПријавите се и изаберите нову лозинку. Ако је неко други захтевао ову радњу или сте се сетили лозинке и не желите да је мењате, занемарите ову поруку и наставите користити стару лозинку.",
        "passwordreset-emailtext-user": "{{GENDER:$1|Корисник је затражио|Корисница је затражила}} подсетник о подацима за пријаву на викију {{SITENAME}} ($4).\nСледећи {{PLURAL:$3|кориснички налог је повезан|кориснички налози су повезани}} с овом имејл адресом:\n\n$2\n\n{{PLURAL:$3|Привремена лозинка истиче|Привремене лозинке истичу}} за {{PLURAL:$5|један дан|$5 дана}}.\nПријавите се и изаберите нову лозинку. Ако је неко други захтевао ову радњу или сте се сетили лозинке и не желите да је мењате, занемарите ову поруку.",
        "passwordreset-emailelement": "Корисничко име: \n$1\n\nПривремена лозинка: \n$2",
-       "passwordreset-emailsentemail": "Ако је ово имејл адреса регистована на Вашем налогу, подсетник о лозинци ће бити послат на имејл.",
+       "passwordreset-emailsentemail": "Ако је ово имејл адреса повезана са Вашим налогом, подсетник о лозинци ће бити послат на имејл.",
        "passwordreset-emailsentusername": "Ако сте навели имејл адресу приликом регистрације, биће послат имејл за ресетовање лозинке.",
        "passwordreset-emailsent-capture": "Послат је подсетник преко имејла, који је приказан доле.",
        "passwordreset-emailerror-capture": "Имејл за ресетовање лозинке, приказан испод је послат, али слање {{GENDER:$2|кориснику|корисници}} није успело: $1",
        "minoredit": "мања измена",
        "watchthis": "надгледај ову страницу",
        "savearticle": "Сачувај страницу",
+       "savechanges": "Сачувај измене",
+       "publishpage": "Објави страницу",
+       "publishchanges": "Објави измене",
        "preview": "Претпреглед",
        "showpreview": "Прикажи претпреглед",
        "showdiff": "Прикажи измене",
        "userpage-userdoesnotexist": "Кориснички налог „<nowiki>$1</nowiki>“ није отворен.\nРазмислите да ли заиста желите да направите/уредите ову страницу.",
        "userpage-userdoesnotexist-view": "Кориснички налог „$1“ није отворен.",
        "blocked-notice-logextract": "Овај корисник је тренутно блокиран.\nИзвештај о последњем блокирању можете погледати испод:",
-       "clearyourcache": "'''Напомена:''' након чувања, можда ћете морати да очистите кеш прегледача.\n*'''Фајерфокс и Сафари:''' држите ''Shift'' и кликните на ''Освежи'', или притисните ''Ctrl-F5'' или Ctrl-R (''⌘-R'' на Макинтошу)\n*'''Гугл кроум:''' притисните ''Ctrl-Shift-R'' (''⌘-Shift-R'' на Макинтошу)\n*'''Интернет експлорер: '''држите ''Ctrl'' и кликните на ''Освежи'', или притисните ''Ctrl-F5''\n*'''Опера:''' очистите привремену меморију преко менија ''Алатке → Поставке''.",
+       "clearyourcache": "<strong>Напомена:</strong> након чувања, можда ћете морати да очистите кеш прегледача како бисте видели промене.\n* <strong>Фајерфокс / Сафари:</strong> држите <em>Shift</em> и кликните на <em>Освежи</em>, или притисните <em>Ctrl-F5</em> или <em>Ctrl-R (<em>⌘-R</em> на Меку)\n* <strong>Гугл кроум:</strong> притисните <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> на Меку)\n* <strong>Интернет експлорер:</strong> држите <em>Ctrl</em> и кликните на <em>Освежи</em> или притисните <em>Ctrl-F5</em>\n* <strong>Опера:</strong> идите на <em>Алатке → Подешавања</em> (<em>Опера → Поставке</em> на Меку) и затим <em>Приватност и безбедност → Очистите податке о прегледима → Кеширане слике и датотеке</em>.",
        "usercssyoucanpreview": "'''Савет:''' кориситите дугме „{{int:showpreview}}“ да испробате свој нови CSS пре него што га сачувате.",
        "userjsyoucanpreview": "'''Савет:''' кориситите дугме „{{int:showpreview}}“ да испробате свој нови јаваскрипт пре него што га сачувате.",
        "usercsspreview": "'''Ово је само преглед CSS-а.'''\n'''Страница још није сачувана!'''",
        "previewnote": "<strong>Ово је претпреглед.</strong>\nВаше измене још нису сачуване!",
        "continue-editing": "Иди на уређивачки оквир",
        "previewconflict": "Овај преглед осликава како ће текст у текстуалном оквиру изгледати.",
-       "session_fail_preview": "'''Нисмо могли да обрадимо вашу измену због губитка података сесије.'''\nПокушајте поново.\nАко и даље не ради, покушајте да се [[Special:UserLogout|одјавите]] и поново пријавите.",
-       "session_fail_preview_html": "'''Нисмо могли да обрадимо вашу измену због губитка података сесије.'''\n\n''Будући да је на овом викију омогућен унос HTML ознака, преглед је сакривен као мера предострожности против напада преко јаваскрипта.''\n\n'''Ако сте покушали да направите праву измену, покушајте поново.\nАко и даље не ради, покушајте да се [[Special:UserLogout|одјавите]] и поново пријавите.'''",
+       "session_fail_preview": "Нисмо могли да обрадимо вашу измену због губитка података сесије.\n\nМожда сте одјављени. <strong>Проверите да ли сте пријављен и покушајте поново</strong>.\n\nАко и даље не ради, покушајте да се [[Special:UserLogout|одјавите]] и поново пријавите и проверите да ли су на Вашем претраживачу дозвољени колачићи са овог сајта.",
+       "session_fail_preview_html": "Нисмо могли да обрадимо вашу измену због губитка података сесије.\n\n<em>Будући да је на овом викију омогућен унос HTML ознака, преглед је сакривен као мера предострожности против напада преко јаваскрипта.</em>\n\n<strong>Ако сте покушали да направите праву измену, покушајте поново.<strong>\nАко и даље не ради, покушајте да се [[Special:UserLogout|одјавите]] и поново пријавите и проверите да ли Ваш претраживач дозвољава колачиће са овог сајта.",
        "token_suffix_mismatch": "'''Ваша измена је одбачена јер је ваш прегледач убацио знакове интерпункције у новчић уређивања.\nТо се понекад догађа када се користи неисправан посредник.'''",
        "edit_form_incomplete": "<strong>Неки делови обрасца за уређивање нису стигли до сервера. Проверите да ли су ваше измене непромењене и покушајте поново.</strong>",
        "editing": "Уређујете $1",
        "userrights-unchangeable-col": "Групе које не можете да промените",
        "userrights-irreversible-marker": "$1*",
        "userrights-conflict": "Сукоб промена корисничких права! Молимо проверите ваше измене.",
-       "userrights-removed-self": "УÑ\81пеÑ\88но Ñ\81Ñ\82е Ñ\81еби Ñ\81кинÑ\83ли Ð¿Ñ\80ава. Ð\97бог Ñ\82ога Ð½Ð¸Ñ\98е Ð²Ð°Ð¼ дозвољен приступ овој страници.",
+       "userrights-removed-self": "СкинÑ\83ли Ñ\81Ñ\82е Ñ\81еби Ð¿Ñ\80ава. Ð\97бог Ñ\82ога Ð\92ам Ð½Ð¸Ñ\98е дозвољен приступ овој страници.",
        "group": "Група:",
        "group-user": "Корисници",
        "group-autoconfirmed": "Аутоматски потврђени корисници",
        "group-bot-member": "{{GENDER:$1|бот}}",
        "group-sysop-member": "{{GENDER:$1|администратор|администраторка|администратор}}",
        "group-bureaucrat-member": "{{GENDER:$1|бирократа}}",
-       "group-suppress-member": "{{GENDER:$1|ревизор|ревизорка}}",
+       "group-suppress-member": "{{GENDER:$1|брисач измена}}",
        "grouppage-user": "{{ns:project}}:Корисници",
        "grouppage-autoconfirmed": "{{ns:project}}:Аутоматски потврђени корисници",
        "grouppage-bot": "{{ns:project}}:Ботови",
        "grant-createeditmovepage": "Прављење, уређивање и премештање страница",
        "grant-delete": "Брисање страница, измена и уноса у дневницима",
        "grant-editinterface": "Уређивање Медијавики именског простора и корисничких CSS/JavaScript страница",
+       "grant-editmycssjs": "Уређивање вашег CSS/JavaScript-а",
        "grant-editmyoptions": "Уређивање ваших подешавања",
        "grant-editmywatchlist": "Уређивање вашег списка надгледања",
        "grant-editpage": "Уређивање постојећих страница",
        "grant-editprotected": "Уређивање заштићених страница",
+       "grant-patrol": "Патролирање измена",
        "grant-protect": "Закључавање и откључавање страница",
        "grant-rollback": "Враћање измена",
+       "grant-sendemail": "Слање имејлова другим корисницима",
        "grant-uploadeditmovefile": "Отпремање, замена и премештање датотека",
        "grant-uploadfile": "Слање нових датотека",
        "grant-basic": "Основна права",
        "uploadstash-summary": "Ова страница пружа приступ датотекама које су послате (или се шаљу), али још нису објављене. Ове датотеке су видљиве само кориснику који га је послао.",
        "uploadstash-clear": "Очисти сакривене датотеке",
        "uploadstash-nofiles": "Немате сакривене датотеке.",
-       "uploadstash-badtoken": "Извршавање дате радње није успело. Разлог томе може бити истек времена за уређивање. Покушајте поново.",
+       "uploadstash-badtoken": "Извршавање дате радње није успело, разлог томе може бити истек времена за уређивање. Покушајте поново.",
        "uploadstash-errclear": "Чишћење датотека није успело.",
        "uploadstash-refresh": "Освежи списак датотека",
        "invalid-chunk-offset": "Неисправна полазна тачка",
        "listgrouprights-namespaceprotection-restrictedto": "Права потребна за уређивање",
        "listgrants-rights": "Права",
        "trackingcategories": "Медијавики категорије",
-       "trackingcategories-summary": "Ð\9eва Ð¿Ð¾Ñ\81ебна Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ñ\81пиÑ\81ак ÐºÐ°Ñ\82егоÑ\80иÑ\98а ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð´ÐµÐ¾ Ð\9cедиÑ\98авикиÑ\98а, Ð¾Ð½Ðµ Ñ\81е Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð°Ð¶Ñ\83Ñ\80иÑ\80аÑ\98Ñ\83 Ð¸ Ñ\9aиÑ\85ови Ð½Ð°Ð·Ð¸Ð²Ð¸ Ñ\81е Ð¼Ð¾Ð³Ñ\83 Ð¼ÐµÑ\9aаÑ\9aаÑ\82и Ñ\83Ñ\80еÑ\92иваÑ\9aем Ñ\81иÑ\81Ñ\82емÑ\81киÑ\85 Ð¿Ð¾Ñ\80Ñ\83ка Ñ\83 Ð¸Ð¼ÐµÐ½Ñ\81ком Ð¿Ñ\80оÑ\81Ñ\82оÑ\80Ñ\83 {{ns:8}}.",
+       "trackingcategories-summary": "Ова посебна страница је списак категорија које су део Медијавикија, оне се аутоматски ажурирају и њихови називи се могу мењати уређивањем системских порука у именском простору {{ns:8}}.",
        "trackingcategories-name": "Име поруке",
        "trackingcategories-desc": "Које странице се налазе у категорији",
        "noindex-category-desc": "Странице које у себи имају магичну реч <code><nowiki>__NOINDEX__</nowiki></code>.",
        "tooltip-ca-nstab-category": "Погледајте страницу категорија",
        "tooltip-minoredit": "Означите измену као мању",
        "tooltip-save": "Сачувајте измене које сте направили",
+       "tooltip-publish": "Објави своје измене",
        "tooltip-preview": "Прегледајте своје измене. Пожељно је да користите ово дугме пре чувања",
        "tooltip-diff": "Погледајте све измене које сте направили на тексту",
        "tooltip-compareselectedversions": "Погледаjте разлике између две изабране измене ове странице.",
        "previousdiff": "← Старија измена",
        "nextdiff": "Новија измена →",
        "mediawarning": "<strong>Упозорење:</strong> ова врста датотеке може садржати штетан код.\nАко га покренете, Ваш рачунар може бити угрожен.",
-       "imagemaxsize": "Ограничење величине слике:<br />''(на страницама за опис датотека)''",
+       "imagemaxsize": "Ограничење величине слике:<br /><em>(на страницама за опис датотека)</em>",
        "thumbsize": "Величина минијатуре:",
        "widthheight": "$1 × $2",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|страница|странице|страница}}",
        "version-libraries-license": "Лиценца",
        "version-libraries-description": "Опис",
        "version-libraries-authors": "Аутори",
-       "redirect": "Преусмерење на датотеку, корисника, страницу или измену",
+       "redirect": "Преусмерење на датотеку, корисника, страницу, измену или дневник",
        "redirect-submit": "Иди",
        "redirect-lookup": "Тип вредности:",
        "redirect-value": "Вредност:",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
        "mw-widgets-titleinput-description-new-page": "страница још увек не постоји",
        "mw-widgets-titleinput-description-redirect": "преусмерава на $1",
-       "api-error-blacklisted": "Изаберите другачији, описан назив.",
        "randomrootpage": "Случајна коренска страница",
        "log-action-filter-block": "Тип блокирања:",
        "log-action-filter-contentmodel": "Тип промене модела садржаја:",
index 996d191..ad1dc2e 100644 (file)
        "minoredit": "manja izmena",
        "watchthis": "nadgledaj ovu stranicu",
        "savearticle": "Sačuvaj stranicu",
-       "preview": "Pregled",
+       "savechanges": "Sačuvaj izmene",
+       "publishpage": "Objavi stranicu",
+       "publishchanges": "Objavi izmene",
+       "preview": "Pretpregled",
        "showpreview": "Prikaži pretpregled",
        "showdiff": "Prikaži izmene",
        "blankarticle": "<strong>Upozorenje:</strong> stranica koju pravite nema nikakav sadržaj.\nAko još jednom pritisnete „{{int:savearticle}}“ napravićete praznu stranicu.",
        "userpage-userdoesnotexist": "Korisnički nalog „<nowiki>$1</nowiki>“ nije otvoren.\nRazmislite da li zaista želite da napravite/uredite ovu stranicu.",
        "userpage-userdoesnotexist-view": "Korisnički nalog „$1“ nije otvoren.",
        "blocked-notice-logextract": "Ovaj korisnik je trenutno blokiran.\nIzveštaj o poslednjem blokiranju možete pogledati ispod:",
-       "clearyourcache": "'''Napomena:''' nakon čuvanja, možda ćete morati da očistite keš pregledača.\n*'''Fajerfoks i Safari:''' držite ''Shift'' i kliknite na ''Osveži'', ili pritisnite ''Ctrl-F5'' ili Ctrl-R (''⌘-R'' na Makintošu)\n*'''Gugl kroum:''' pritisnite ''Ctrl-Shift-R'' (''⌘-Shift-R'' na Makintošu)\n*'''Internet eksplorer: '''držite ''Ctrl'' i kliknite na ''Osveži'', ili pritisnite ''Ctrl-F5''\n*'''Opera:''' očistite privremenu memoriju preko menija ''Alatke → Postavke''.",
+       "clearyourcache": "<strong>Napomena:</strong> nakon čuvanja, možda ćete morati da očistite keš pregledača kako biste videli promene.\n* <strong>Fajerfoks / Safari:</strong> držite <em>Shift</em> i kliknite na <em>Osveži</em>, ili pritisnite <em>Ctrl-F5</em> ili <em>Ctrl-R (<em>⌘-R</em> na Meku)\n* <strong>Gugl kroum:</strong> pritisnite <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> na Meku)\n* <strong>Internet eksplorer:</strong> držite <em>Ctrl</em> i kliknite na <em>Osveži</em> ili pritisnite <em>Ctrl-F5</em>\n* <strong>Opera:</strong> idite na <em>Alatke → Podešavanja</em> (<em>Opera → Postavke</em> na Meku) i zatim <em>Privatnost i bezbednost → Očistite podatke o pregledima → Keširane slike i datoteke</em>.",
        "usercssyoucanpreview": "'''Savet:''' korisitite dugme „{{int:showpreview}}“ da isprobate svoj novi CSS pre nego što ga sačuvate.",
        "userjsyoucanpreview": "'''Savet:''' korisitite dugme „{{int:showpreview}}“ da isprobate svoj novi javaskript pre nego što ga sačuvate.",
        "usercsspreview": "'''Ovo je samo pregled CSS-a.'''\n'''Stranica još nije sačuvana!'''",
        "rev-showdeleted": "prikaži",
        "revisiondelete": "Obriši/vrati izmene",
        "revdelete-nooldid-title": "Nema tražene izmene",
-       "revdelete-nooldid-text": "Niste naveli željenu izmenu, ona ne postoji ili pokušavate da je sakrijete.",
+       "revdelete-nooldid-text": "Niste izabrali odredišnu izmenu na kojoj treba da se izvrši ova funkcija, ta izmena ne postoji, ili pokušavate sakriti trenutnu izmenu.",
        "revdelete-no-file": "Tražena datoteka ne postoji.",
        "revdelete-show-file-confirm": "Želite li da vidite obrisanu izmenu datoteke „<nowiki>$1</nowiki>“ od $2; $3?",
        "revdelete-show-file-submit": "Da",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrator|administratorka}}",
        "group-bureaucrat-member": "{{GENDER:$1|birokrata}}",
-       "group-suppress-member": "{{GENDER:$1|revizor|revizorka}}",
+       "group-suppress-member": "{{GENDER:$1|brisač izmena}}",
        "grouppage-user": "{{ns:project}}:Korisnici",
        "grouppage-autoconfirmed": "{{ns:project}}:Automatski potvrđeni korisnici",
        "grouppage-bot": "{{ns:project}}:Botovi",
        "listgrouprights-namespaceprotection-restrictedto": "Prava potrebna za uređivanje",
        "listgrants-rights": "Prava",
        "trackingcategories": "Medijaviki kategorije",
-       "trackingcategories-summary": "Ova posebna stranica je spisak kategorija koje su deo Medijavikija, one se automatski ažuriraju i njihovi nazivi se mogu menjanjati uređivanjem sistemskih poruka u imenskom prostoru {{ns:8}}.",
+       "trackingcategories-summary": "Ova posebna stranica je spisak kategorija koje su deo Medijavikija, one se automatski ažuriraju i njihovi nazivi se mogu menjati uređivanjem sistemskih poruka u imenskom prostoru {{ns:8}}.",
        "trackingcategories-name": "Ime poruke",
        "trackingcategories-desc": "Koje stranice se nalaze u kategoriji",
        "noindex-category-desc": "Stranice koje u sebi imaju magičnu reč <code><nowiki>__NOINDEX__</nowiki></code>.",
        "tooltip-ca-nstab-category": "Pogledajte stranicu kategorija",
        "tooltip-minoredit": "Označite izmenu kao manju",
        "tooltip-save": "Sačuvajte izmene koje ste napravili",
+       "tooltip-publish": "Objavi svoje izmene",
        "tooltip-preview": "Pregledajte svoje izmene. Poželjno je da koristite ovo dugme pre čuvanja",
        "tooltip-diff": "Pogledajte sve izmene koje ste napravili na tekstu",
        "tooltip-compareselectedversions": "Pogledajte razlike između dve izabrane izmene ove stranice.",
        "previousdiff": "← Starija izmena",
        "nextdiff": "Novija izmena →",
        "mediawarning": "<strong>Upozorenje:</strong> ova vrsta datoteke može sadržati štetan kod.\nAko ga pokrenete, Vaš računar može biti ugrožen.",
-       "imagemaxsize": "Ograničenje veličine slike:<br />''(na stranicama za opis datoteka)''",
+       "imagemaxsize": "Ograničenje veličine slike:<br /><em>(na stranicama za opis datoteka)</em>",
        "thumbsize": "Veličina minijature:",
        "widthheight": "$1 × $2",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|stranica|stranice|stranica}}",
        "mw-widgets-dateinput-placeholder-month": "GGGG-MM",
        "mw-widgets-titleinput-description-new-page": "stranica još uvek ne postoji",
        "mw-widgets-titleinput-description-redirect": "preusmerava na $1",
-       "api-error-blacklisted": "Izaberite drugačiji, opisan naziv.",
        "randomrootpage": "Slučajna korenska stranica"
 }
index 4f61cf7..6b1f4dd 100644 (file)
@@ -71,7 +71,8 @@
                        "Dammråtta",
                        "Mgr",
                        "Matma Rex",
-                       "McDutchie"
+                       "McDutchie",
+                       "Larske"
                ]
        },
        "tog-underline": "Stryk under länkar:",
        "content-model-css": "CSS",
        "content-json-empty-object": "Tomt objekt",
        "content-json-empty-array": "Tomt fält",
+       "deprecated-self-close-category": "Sidor som använder ogiltiga självstängda HTML-taggar",
+       "deprecated-self-close-category-desc": "Sidan använder ogiltiga självstängda HTML-taggar, som <code>&lt;b/></code> eller <code>&lt;span/></code>.  Beteendet för dessa kommer snart att ändras för att bli konsistent med HTML5-specifikationen, så dessa anses vara för föråldrade för att använda i wikitext.",
        "duplicate-args-warning": "<strong>Varning:</strong> [[:$1]] anropar [[:$2]] med mer än ett värde för parametern \"$3\". Endast det sista värdet kommer att användas.",
        "duplicate-args-category": "Sidor som använder upprepade argument i mallanrop",
        "duplicate-args-category-desc": "Sidan innehåller mallanrop som använder repeterade argument, så som <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> eller <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "ÅÅÅÅ-MM",
        "mw-widgets-titleinput-description-new-page": "sidan existerar inte ännu",
        "mw-widgets-titleinput-description-redirect": "omdirigerar till $1",
-       "api-error-blacklisted": "Välj en annan beskrivande titel.",
        "sessionmanager-tie": "Kan inte kombinera flera begäransautentiseringstyper: $1.",
        "sessionprovider-generic": "$1-sessioner",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "cookiebaserade sessioner",
        "log-action-filter-newusers": "Typ av kontoskapande:",
        "log-action-filter-patrol": "Typ av patrullering:",
        "log-action-filter-protect": "Typ av skydd:",
-       "log-action-filter-rights": "Typ av rättighetsändring",
-       "log-action-filter-suppress": "Censurtyp",
+       "log-action-filter-rights": "Typ av rättighetsändring:",
+       "log-action-filter-suppress": "Censurtyp:",
        "log-action-filter-upload": "Typ av uppladdning:",
        "log-action-filter-all": "Alla",
        "log-action-filter-block-block": "Blockering",
index fc4a91b..ccd1f6c 100644 (file)
        "mw-widgets-dateinput-no-date": "திகதி தெரிவுச் செய்யப்படவில்லை",
        "mw-widgets-titleinput-description-new-page": "இப்பக்கம் இன்னும் உருவாக்கப்படவில்லை",
        "mw-widgets-titleinput-description-redirect": "$1-க்கு வழிமாற்று",
-       "api-error-blacklisted": "தயவுகூர்ந்து வேறு, விளக்கமான தலைப்பைத் தேர்ந்தெடுக்கவும்.",
        "sessionprovider-generic": "$1 பகுதி",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "குக்கீயை அடிபடையாக்கக் கொண்ட பகுதிகள்",
        "sessionprovider-nocookies": "குக்கீசு செயலற்று இருக்கலாம். உங்களது குக்கீசு செயலில் உள்ளது என உறுதிப்படுத்திவிட்டு மீண்டும் முயல்க.",
index 662edaf..068b570 100644 (file)
        "mainpage-description": "ಮುಖ್ಯ ಪುಟ",
        "policy-url": "Project:ನಿಯಮಾವಳಿ",
        "portal": "ಸಮುದಾಯೊ ಪುಟೊ",
-       "portal-url": "Project:ಸಮುದಾಯ ಪುಟ",
+       "portal-url": "Project:ಸಮುದಾಯ ಪುಟ",
        "privacy": "ಕಾಸಗಿ ಕಾರ್ಯೊನೀತಿ",
        "privacypage": "Project:ಕಾಸಗಿ ಕಾರ್ಯೊನೀತಿ",
        "badaccess": "ಅನುಮತಿ ದೋಷ",
        "createacct-submit": "ಪೊಸ ಕಾತೆ ಸುರು ಮಲ್ಪುಲೆ",
        "createacct-another-submit": "ಪೊಸ ಕಾತೆ ಸುರು ಮಲ್ಪುಲೆ",
        "createacct-benefit-heading": "{{SITENAME}}ನಿಕ್ಲೆನಂಚಿತ್ತಿನ ಜನೊಕ್ಲೆಡ್ದ್ ಉಂಡಾಪುಂಡು.",
-       "createacct-benefit-body1": "{{PLURAL:$1|ಸà²\82ಪದನà³\86|ಸà²\82ಪದನೆಲು}}",
+       "createacct-benefit-body1": "{{PLURAL:$1|ಸà²\82ಪà³\8aದನà³\86|ಸà²\82ಪದà³\8aನೆಲು}}",
        "createacct-benefit-body2": "{{PLURAL:$1|ಪುಟೊ|ಪುಟೊಕ್ಕುಲು}}",
        "createacct-benefit-body3": "{{PLURAL:$1|ಇನಾಮು|ಇನಾಮುಲು}}",
        "badretype": "ಈರ್ ಕೊರ್ನ ಪ್ರವೇಶ ಪದೆ ಬೇತೆ ಬೇತೆ ಅತ್ಂಡ್",
        "minoredit": "ಉಂದು ಎಲ್ಯ ಬದಲಾವಣೆ",
        "watchthis": "ಈ ಪುಟೊನು ತೂಲೆ",
        "savearticle": "ಪುಟೊನು ಒರಿಪಾಲೆ",
+       "savechanges": "ಬದಲಾವನೆನ್ ಒರಿಪಾಲೆ",
        "publishpage": "ಪುಟೋನು ಪ್ರಕಟಿಸಲೇ",
+       "publishchanges": "ಬದಲಾವನೆನ್ ತೋಜಾಲೆ",
        "preview": "ಮುನ್ನೋಟ",
        "showpreview": "ಮುನ್ನೋಟೊ ತೋಜಾವು",
        "showdiff": "ಬದಲಾವಣೆಲೆನ್ ತೋಜಾವ್",
        "mergehistory-reason": "ಕಾರಣ:",
        "revertmerge": "ಅನ್-ಮರ್ಜ್ ಮಲ್ಪುಲೆ",
        "history-title": "\"$1\" ಪುಟೊತ ಆವೃತ್ತಿ ಇತಿಹಾಸೊ",
-       "difference-title": "ಪಿರ à²ªà²°à²¿à²¸à³\80ಲನà³\86ದ à²¨à²¡à³\81ತ à²µà³\8dಯತà³\8dವಾಸೊ \"$1\"",
+       "difference-title": "ಪಿರ à²ªà²°à²¿à²¸à³\80ಲನà³\86ದ à²¨à²¡à³\81ತ à²µà³\8dಯತà³\8dಯಾಸೊ \"$1\"",
        "lineno": "$1ನೇ ಸಾಲ್:",
        "compareselectedversions": "ಆಯ್ಕೆ ಮಲ್ತಿನ ಆವೃತ್ತಿಲೆನ್ ಹೊಂದಾಣಿಕೆ ಮಲ್ತ್ ತೂಲೆ",
        "editundo": "ದುಂಬುದಲೆಕೊ",
index 385deaa..a4a02e3 100644 (file)
        "log-action-filter-delete": "Silme türü:",
        "log-action-filter-patrol": "Devriye türü:",
        "log-action-filter-protect": "Koruma tipi:",
+       "log-action-filter-rights": "Hak türü seçimi:",
+       "log-action-filter-suppress": "Kaldırma türü:",
        "log-action-filter-upload": "Yükleme türü:",
        "log-action-filter-all": "Tümü",
        "log-action-filter-block-block": "Blok",
index 79a6f94..48bbe1f 100644 (file)
        "minoredit": "Незначна зміна",
        "watchthis": "Спостерігати за цією сторінкою",
        "savearticle": "Зберегти сторінку",
+       "savechanges": "Зберегти зміни",
        "publishpage": "Опублікувати сторінку",
+       "publishchanges": "Опублікувати зміни",
        "preview": "Попередній перегляд",
        "showpreview": "Попередній перегляд",
        "showdiff": "Показати зміни",
        "content-model-css": "CSS",
        "content-json-empty-object": "Порожній об'єкт",
        "content-json-empty-array": "Порожній масив",
+       "deprecated-self-close-category": "Сторінки, що використовують недійсні самозакривні теги HTML",
+       "deprecated-self-close-category-desc": "Сторінка містить недійсні самозакривні теги HTML, наприклад, <code>&lt;b/></code> чи <code>&lt;span/></code>.  Їхню поведінку невдовзі буде змінено у відповідності зі специфікацією HTML5, тому їх використання у вікітексті є застарілим.",
        "duplicate-args-warning": "<strong>Увага:</strong> [[:$1]] викликає [[:$2]] з більш ніж одним значенням параметра «$3». Буде використано лише останнє вказане значення.",
        "duplicate-args-category": "Сторінки, що містять шаблон із кількома значеннями одного й того ж параметра",
        "duplicate-args-category-desc": "Тут перелічено сторінки, що містять дублікатне визначення аргументу при включенні шаблону, приміром, <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> або <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "booksources-text": "На цій сторінці наведено список посилань на сайти, де ви, можливо, знайдете додаткову інформацію про книгу. Це інтернет-магазини й системи пошуку в бібліотечних каталогах.",
        "booksources-invalid-isbn": "Вказаний номер ISBN, судячи з усього, містить помилку. Будь ласка, перевірте, що при перенесенні номера з першоджерела не виникло спотворень.",
        "specialloguserlabel": "Виконавець:",
-       "speciallogtitlelabel": "Ціль (назва сторінки або {{ns:user}}:ім'я користувача):",
+       "speciallogtitlelabel": "Ціль (назва сторінки або {{ns:user}}:Ім'я_користувача):",
        "log": "Журнали",
        "logeventslist-submit": "Показати",
        "all-logs-page": "Усі публічні журнали",
        "mw-widgets-dateinput-placeholder-month": "РРРР-ММ",
        "mw-widgets-titleinput-description-new-page": "сторінка ще не існує",
        "mw-widgets-titleinput-description-redirect": "перенаправлення на $1",
-       "api-error-blacklisted": "Будь ласка, виберіть іншу, більш зрозумілу назву.",
        "sessionmanager-tie": "Не можна поєднувати кілька типів автентифікації запиту: $1.",
        "sessionprovider-generic": "сесій $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "сесій на основі кук",
        "log-action-filter-newusers": "Тип створення облікового запису:",
        "log-action-filter-patrol": "Тип патрулювання:",
        "log-action-filter-protect": "Тип захисту:",
-       "log-action-filter-rights": "Тип зміни прав",
-       "log-action-filter-suppress": "Тип приховування",
+       "log-action-filter-rights": "Тип зміни прав:",
+       "log-action-filter-suppress": "Тип приховування:",
        "log-action-filter-upload": "Тип завантаження:",
        "log-action-filter-all": "Усі",
        "log-action-filter-block-block": "Блокування",
index 7ddfea5..fdc8ec5 100644 (file)
        "nologin": "کیا آپ نے کھاتہ نہیں بنایا ہوا؟ '''$1'''۔",
        "nologinlink": "کھاتا بنائیں",
        "createaccount": "کھاتہ کھولیں",
-       "gotaccount": "پہلے سے کھاتہ بنا ہوا ہے? '''$1'''.",
+       "gotaccount": "پہلے سے کھاتہ بنا ہوا ہے؟ '''$1'''۔",
        "gotaccountlink": "داخل ہوجائیے",
        "userlogin-resetlink": "داخلِ نوشتہ ہونے کی تفاصیل بھول گئے ہیں؟",
        "userlogin-resetpassword-link": "کلمہ شناخت بھول گئے؟",
        "defaultmessagetext": "طے شدہ پیغام کا متن",
        "content-model-text": "سادہ متن",
        "content-model-javascript": "جاوا اسکرپٹ",
+       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|تبادلہ خیال]]) کی جانب سے کی گئی ترمیم $1 رد کردی گئی ہے۔",
        "viewpagelogs": "اس صفحہ کیلیے نوشتہ جات دیکھیے",
        "nohistory": "اِس صفحہ کیلئے کوئی تدوینی تاریخچہ موجود نہیں ہے.",
        "currentrev": "حـالیـہ تـجدید",
        "history-show-deleted": "صرف حذف شدہ",
        "histfirst": "قدیم ترین",
        "histlast": "تازہ ترین",
-       "historysize": "({{PLURAL:$1|1 لکمہ|$1 لکم}})",
+       "historysize": "({{PLURAL:$1|1 بائٹ|$1 بائٹ}})",
        "historyempty": "(خالی)",
        "history-feed-title": "تاریخچۂ نظرثانی",
        "history-feed-description": "ویکی پر اِس صفحہ کا تاریخچۂ نظرثانی",
        "group-user-member": "صارف",
        "group-autoconfirmed-member": "خودتوثیق شدہ صارف",
        "group-bot-member": "خودکار صارف",
-       "group-sysop-member": "منتظم",
+       "group-sysop-member": "{{GENDER:$1|منتظم}}",
        "group-bureaucrat-member": "{{GENDER:$1|مامور اداری}}",
        "group-suppress-member": "{{GENDER:$1|suppressor}}",
        "grouppage-user": "{{ns:project}}:صارفین",
        "grouppage-autoconfirmed": "{{ns:project}}:خود توثیق شدہ صارف",
        "grouppage-bot": "{{ns:project}}:روبہ جات",
        "grouppage-sysop": "{{ns:project}}:منتظمین",
-       "grouppage-bureaucrat": "بیورو کریٹ",
+       "grouppage-bureaucrat": "{{ns:project}}:مامورین اداری",
        "right-upload": "ملفات زبراثقال (اپ لوڈ) کریں",
        "right-writeapi": "اے پی آئی لکھائی کا استعمال",
        "right-delete": "صفحات حذف کریں",
        "newpageletter": "نیا ..",
        "boteditletter": " خودکار",
        "rc_categories_any": "کوئی بھی منتخب",
-       "rc-change-size-new": "$1 {{PLURAL:$1|بائٹ|بائٹس}} تبدیلی کے بعد",
+       "rc-change-size-new": "$1 {{PLURAL:$1|بائٹ|بائٹ}} تبدیلی کے بعد",
        "rc-enhanced-expand": "تفصیلات دکھائیں",
        "rc-enhanced-hide": "تفصیلات چھپائیے",
        "recentchangeslinked": "متعلقہ تبدیلیاں",
        "ilsubmit": "تلاش",
        "bydate": "بالحاظ تاریخ",
        "weeks": "{{PLURAL:$1|$1ہفتہ| $1  ہفتے}}",
+       "ago": "$1 قبل",
+       "minutes-ago": "$1 {{PLURAL:$1|منٹ|منٹ}} قبل",
+       "seconds-ago": "$1 {{PLURAL:$1|سیکنڈ|سیکنڈ}} قبل",
        "bad_image_list": "شکلبند درج ذیل ہے:\n\nصرف فہرستی عناصر (* سے شروع ہونے والی لکیری) شامل کی جاتی ہیں۔\nکسی لکیر میں پہلا ربط کوئی خراب ملف کا ہونا چاہئے۔\nاُسی لکیر میں باقی آنے والے ربط کو مستثنیٰ قرار دیا جاتا ہے، مثلاً صفحات جہاں ملف لکیر کے وسط میں آسکتا ہے۔",
        "metadata": "میٹا ڈیٹا",
        "metadata-help": "اِس ملف میں اِضافی معلومات شامل ہیں، جو کہ شاید اُس رقمی کیمرے یا سکینر سے آئے ہیں جس کے ذریعے یہ ملف بنائی گئی تھی۔\nاگر ملف اپنی اصل حالت میں نہیں رہی ہے تو کچھ تفاصیل ترمیم شدہ ملف کی مکمل طور پر عکاسی نہیں کرپائیں گے۔",
        "logentry-move-move": "$1 نے صفحہ $3 کو بجانب $4 منتقل کیا",
        "logentry-newusers-create": "صارف کھاتہ $1 {{GENDER:$2|بنایا گیا}}",
        "logentry-protect-modify": "$1 نے $3 کا درجۂ حفاظت {{GENDER:$2|تبدیل کیا}} $4",
+       "logentry-rights-rights": "$1 نے {{GENDER:$6|$3}} کی گروہی رکنیت از $4 تا $5 {{GENDER:$2|تبدیل کی}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|اپلوڈ}} $3",
        "rightsnone": "(کچھ نہیں)",
        "revdelete-summary": "خلاصۂ تدوین",
index 13c056b..3715253 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "Đối tượng trống",
        "content-json-empty-array": "Mảng trống",
+       "deprecated-self-close-category": "Trang có thẻ HTML tự đóng không hợp lệ",
        "duplicate-args-warning": "<strong>Cảnh báo:</strong> [[:$1]] đang gọi  [[:$2]] với nhiều hơn một giá trị cho thông số “$3”. Chỉ giá trị cuối cùng mới được sử dụng.",
        "duplicate-args-category": "Trang đưa đối số thừa vào bản mẫu",
        "duplicate-args-category-desc": "Trang đưa một đối số nhiều lần vào một bản mẫu được nhúng, thí dụ <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> hoặc <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "mw-widgets-dateinput-placeholder-month": "YYYY-MM (năm-tháng)",
        "mw-widgets-titleinput-description-new-page": "trang này chưa tồn tại",
        "mw-widgets-titleinput-description-redirect": "đổi hướng đến $1",
-       "api-error-blacklisted": "Xin vui lòng chọn một tên khác miêu tả đầy đủ.",
        "sessionmanager-tie": "Không thể kết hợp nhiều yêu cầu xác thực loại: $1.",
        "sessionprovider-generic": "phiên $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "phiên dựa trên cookie",
index 3c01f7e..4edc5d8 100644 (file)
        "enhancedrc-history": "歷史",
        "recentchanges": "近段辰光个改动",
        "recentchanges-legend": "近段辰光个改动选项",
-       "recentchanges-summary": "登该个页面浪跟踪最近对维基百科个改动。",
+       "recentchanges-summary": "登该个页面浪跟踪最近对本站个改动。",
        "recentchanges-feed-description": "跟踪此订阅垃拉 wiki 高头个最近更改。",
        "recentchanges-label-newpage": "箇编辑建立着新页",
        "recentchanges-label-minor": "箇是小编写",
index 00b5c78..a0f38be 100644 (file)
        "youhavenewmessagesmanyusers": "您有来自多个用户的$1($2)。",
        "newmessageslinkplural": "{{PLURAL:$1|新信息|999=新消息}}",
        "newmessagesdifflinkplural": "最后{{PLURAL:$1|更改|999=更改}}",
-       "youhavenewmessagesmulti": "在$1有新信息",
+       "youhavenewmessagesmulti": "在$1有新信息",
        "editsection": "编辑",
        "editold": "编辑",
        "viewsourceold": "查看源代码",
        "password-login-forbidden": "这个用户名称及密码的使用是被禁止的。",
        "mailmypassword": "重置密码",
        "passwordremindertitle": "{{SITENAME}}的新临时密码",
-       "passwordremindertext": "有人(可能是您,来自IP地址$1)已请求{{SITENAME}}的新密码($4)。\n用户“$2”的一个新临时密码现在已被设置好为“$3”。\n如果这个动作是您所指示的,您便需要立即登录并选择一个新的密码。\n您的临时密码会于$5天内过期。\n\n如果是其他人发出了该请求,或者您已经记起了您的密码并不准备改变它,您可以忽略此消息并继续使用您的旧密码。",
+       "passwordremindertext": "有人(可能是您,来自IP地址$1)已请求{{SITENAME}}的新密码($4)。用户“$2”的一个新临时密码现在已被设置好为“$3”。如果这个动作是您所指示的,您便需要立即登录并选择一个新的密码。您的临时密码会于{{PLURAL:$5|一天|$5天}}内过期。\n\n如果是其他人发出了该请求,或者您已经记起了您的密码并不准备改变它,您可以忽略此消息并继续使用您的旧密码。",
        "noemail": "用户\"$1\"没有登记电子邮件地址。",
        "noemailcreate": "您需要提供一个有效的电子邮件地址",
        "passwordsent": "用户\"$1\"的新密码已经寄往所登记的电子邮件地址。\n请在收到后再登录。",
        "clearyourcache": "<strong>注意:</strong>在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。\n* <strong>Firefox或Safari:</strong>按住<em>Shift</em>的同时单击<em>刷新</em>,或按<em>Ctrl-F5</em>或<em>Ctrl-R</em>(Mac为<em>⌘-R</em>)\n* <strong>Google Chrome:</strong>按<em>Ctrl-Shift-R</em>(Mac为<em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong>按住<em>Ctrl</em>的同时单击<em>刷新</em>,或按<em>Ctrl-F5</em>\n* <strong>Opera:</strong>前往<em>菜单 → 设置</em>(Mac为<em>Opera → Preferences</em>),然后<em>隐私和安全 → 清除浏览数据 → 缓存的图片和文件</em>。",
        "usercssyoucanpreview": "<strong>提示:</strong>在保存前请用“{{int:showpreview}}”按钮来测试您新的 CSS 。",
        "userjsyoucanpreview": "<strong>提示:</strong>在保存前请用“{{int:showpreview}}”按钮来测试您新的 JavaScript 。",
-       "usercsspreview": "<strong>请记住您现在只是在预览的用户CSS。它尚未保存!</strong>",
+       "usercsspreview": "<strong>请记住您现在只是在预览的用户CSS。它尚未保存!</strong>",
        "userjspreview": "<strong>请记住您现在只是在测试/预览您的用户JavaScript。它尚未保存!</strong>",
-       "sitecsspreview": "<strong>请记住现在只是在预览该CSS。它尚未保存!</strong>",
+       "sitecsspreview": "<strong>请记住现在只是在预览该CSS。它尚未保存!</strong>",
        "sitejspreview": "<strong>请记住您现在只是在预览该JavaScript代码。它尚未保存!</strong>",
        "userinvalidcssjstitle": "<strong>警告:</strong>不存在皮肤“$1”。注意自定义的 .css 和 .js 页要使用小写标题,例如,{{ns:user}}:Foo/vector.css 不同于 {{ns:user}}:Foo/Vector.css。",
        "updated": "(已更新)",
        "content-model-css": "CSS",
        "content-json-empty-object": "空的对象",
        "content-json-empty-array": "空的数组",
+       "deprecated-self-close-category": "使用无效自封闭HTML标签的页面",
+       "deprecated-self-close-category-desc": "页面包含无效的自封闭HTML标签,例如<code>&lt;b/></code>或<code>&lt;span/></code>。这些标签的行为将很快被更改以与HTML5规格相一致,所以它们在wiki文本中的使用已弃用。",
        "duplicate-args-warning": "<strong>警告:</strong>[[:$1]]正在调用超过一个[[:$2]]中“$3”参数的值。只有最后提供的值会被使用。",
        "duplicate-args-category": "调用重复模板参数的页面",
        "duplicate-args-category-desc": "页面包含调用了重复参数的模板,例如<code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code>或<code><nowiki>{{foo|bar|1=baz}}</nowiki></code>。",
        "emailpagetext": "您可以使用下面的表格发送电子邮件信息至该{{GENDER:$1|用户}}。您在[[Special:Preferences|系统设置]]中输入的电子邮件地址将显示为邮件的“发件人”地址,所以该用户将可以直接回复您。",
        "defemailsubject": "来自{{SITENAME}}用户“$1”的电子邮件",
        "usermaildisabled": "用户电子邮件停用",
-       "usermaildisabledtext": "不能发送电子邮件至本wiki的其他用户",
+       "usermaildisabledtext": "不能发送电子邮件至本wiki的其他用户",
        "noemailtitle": "无电子邮件地址",
        "noemailtext": "该用户还没有指定一个有效的电子邮件地址。",
        "nowikiemailtext": "该用户已经选择不接收来自其他用户的电子邮件。",
        "markaspatrolleddiff": "标记为已巡查",
        "markaspatrolledtext": "标记此页面为已巡查",
        "markaspatrolledtext-file": "将此文件版本标记为已巡查",
-       "markedaspatrolled": "标记为已查",
+       "markedaspatrolled": "标记为已查",
        "markedaspatrolledtext": "[[:$1]]的已选中版本已被标识为已巡查。",
        "rcpatroldisabled": "最近更改巡查已禁用",
        "rcpatroldisabledtext": "最近更改巡查功能目前已关闭。",
-       "markedaspatrollederror": "不能标志为已检查",
-       "markedaspatrollederrortext": "需要指定一个版本以标记为已巡查。",
-       "markedaspatrollederror-noautopatrol": "你不能把自己的更改标记为已检查。",
+       "markedaspatrollederror": "不能标记为已巡查",
+       "markedaspatrollederrortext": "需要指定一个版本以标记为已巡查。",
+       "markedaspatrollederror-noautopatrol": "您不被允许将您自己的更改标记为已巡查。",
        "markedaspatrollednotify": "$1的更改已被标记为已巡查。",
        "markedaspatrollederrornotify": "标记为已巡查失败。",
        "patrol-log-page": "巡查日志",
        "watchlistedit-raw-submit": "更新监视列表",
        "watchlistedit-raw-done": "您的监视列表已经更新。",
        "watchlistedit-raw-added": "$1个标题被添加:",
-       "watchlistedit-raw-removed": "$1个标题被除:",
+       "watchlistedit-raw-removed": "$1个标题被除:",
        "watchlistedit-clear-title": "清空监视列表",
        "watchlistedit-clear-legend": "清空监视列表",
        "watchlistedit-clear-explain": "所有标题将从您的监视列表中移除",
        "mw-widgets-dateinput-no-date": "没有选定日期",
        "mw-widgets-titleinput-description-new-page": "页面不存在",
        "mw-widgets-titleinput-description-redirect": "重定向至$1",
-       "api-error-blacklisted": "请选择其他描述性的标题。",
        "sessionmanager-tie": "不能结合多个请求的身份验证类型:$1。",
        "sessionprovider-generic": "$1会话",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "基于cookie的会话",
        "log-action-filter-newusers": "账户创建的类型:",
        "log-action-filter-patrol": "巡查类型:",
        "log-action-filter-protect": "保护类型:",
-       "log-action-filter-rights": "权限更改的类型",
-       "log-action-filter-suppress": "屏蔽的类型",
+       "log-action-filter-rights": "权限更改的类型",
+       "log-action-filter-suppress": "屏蔽的类型",
        "log-action-filter-upload": "上传类型:",
        "log-action-filter-all": "全部",
        "log-action-filter-block-block": "封禁",
index 6255bf7..23f0357 100644 (file)
        "content-model-css": "CSS",
        "content-json-empty-object": "空物件",
        "content-json-empty-array": "空陣列",
+       "deprecated-self-close-category": "使用無效 Self-closed HTML 標籤的頁面",
+       "deprecated-self-close-category-desc": "頁面包含無效的 Self-closed HTML 標籤,如 <code>&lt;b/></code> or <code>&lt;span/></code>。這些標籤的模式將會更改為與 HTML5 規格一致,因此 wikitext 的這種用法已停用。",
        "duplicate-args-warning": "<strong>警告:</strong> [[:$1]] 呼叫 [[:$2]] 的 \"$3\" 參數使用了超過一次,僅會使用提供的最後一個參數值。",
        "duplicate-args-category": "模板呼叫時使用重複的參數的頁面",
        "duplicate-args-category-desc": "該頁面包含重複使用參數的模板呼叫,如 <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> 或 <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>。",
        "upload-http-error": "發生 HTTP 錯誤:$1",
        "upload-copy-upload-invalid-domain": "此網域不允許複製上傳的檔案。",
        "upload-foreign-cant-upload": "此 wiki 未設定可上傳來自遠端檔案庫的請求的檔案。",
+       "upload-foreign-cant-load-config": "載入要上傳檔案到遠端檔案儲存庫的設定失敗。",
+       "upload-dialog-disabled": "此 wiki 已關閉使用此對話框上傳檔案的功能。",
        "upload-dialog-title": "上傳檔案",
        "upload-dialog-button-cancel": "取消",
        "upload-dialog-button-done": "完成",
        "watchlistedit-normal-legend": "從監視清單中移除標題",
        "watchlistedit-normal-explain": "下方顯示在您監視清單中的標題。\n要移除標題,請勾選該標題旁的核選方塊並點選 \"{{int:Watchlistedit-normal-submit}}\"。\n您也可 [[Special:EditWatchlist/raw|編輯原始監視清單]]。",
        "watchlistedit-normal-submit": "移除標題",
-       "watchlistedit-normal-done": "已於您的監視清單中移除 $1 個標題:",
+       "watchlistedit-normal-done": "已於您的監視清單中移除 {{PLURAL:$1|$1}} 個標題:",
        "watchlistedit-raw-title": "編輯原始監視清單",
        "watchlistedit-raw-legend": "編輯原始監視清單",
        "watchlistedit-raw-explain": "下方顯示在您監視清單中的標題,您可透過編輯來新增與移除清單項目,一個標題一行。\n完成編輯後,請點選 \"{{int:Watchlistedit-raw-submit}}\"。\n您也可 [[Special:EditWatchlist|使用標準編輯器]]。",
        "mw-widgets-dateinput-no-date": "未選擇日期",
        "mw-widgets-titleinput-description-new-page": "頁面不存在",
        "mw-widgets-titleinput-description-redirect": "重新導向至 $1",
-       "api-error-blacklisted": "請選擇另一個更具描述性的標題。",
        "sessionmanager-tie": "無法合併多個請求認証類型:$1。",
        "sessionprovider-generic": "$1 連線階段",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "以 cookie 為基礎的連線階段",
        "linkaccounts-success-text": "已連結帳號。",
        "linkaccounts-submit": "連結帳號",
        "unlinkaccounts": "取消連結帳號",
-       "unlinkaccounts-success": "已取消連結帳號。"
+       "unlinkaccounts-success": "已取消連結帳號。",
+       "authenticationdatachange-ignored": "認証資料變更未被處理,可能未設定提供者?"
 }
index 18c115b..cc555b6 100644 (file)
@@ -15,7 +15,7 @@ $rtl = true;
 
 $namespaceNames = [
        NS_MEDIA            => 'رسنۍ',
-       NS_SPECIAL          => 'Ú\81اÙ\86Ú«ړی',
+       NS_SPECIAL          => 'Ú\81اÙ\86Ú¯ړی',
        NS_TALK             => 'خبرې_اترې',
        NS_USER             => 'کارن',
        NS_USER_TALK        => 'د_کارن_خبرې_اترې',
@@ -33,6 +33,7 @@ $namespaceNames = [
 ];
 
 $namespaceAliases = [
+       'ځﺎﻧګړی' => NS_SPECIAL,
        'کارونکی' => NS_USER,
        'د_کارونکي_خبرې_اترې' => NS_USER_TALK,
        'انځور' => NS_FILE,
diff --git a/maintenance/cleanupEmptyCategories.php b/maintenance/cleanupEmptyCategories.php
new file mode 100644 (file)
index 0000000..b8a246e
--- /dev/null
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Clean up empty categories in the category table.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script to clean up empty categories in the category table.
+ *
+ * @ingroup Maintenance
+ * @since 1.28
+ */
+class CleanupEmptyCategories extends LoggedUpdateMaintenance {
+
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription(
+                       <<<TEXT
+This script will clean up the category table by removing entries for empty
+categories without a description page and adding entries for empty categories
+with a description page. It will print out progress indicators every batch. The
+script is perfectly safe to run on large, live wikis, and running it multiple
+times is harmless. You may want to use the throttling options if it's causing
+too much load; they will not affect correctness.
+
+If the script is stopped and later resumed, you can use the --mode and --begin
+options with the last printed progress indicator to pick up where you left off.
+
+When the script has finished, it will make a note of this in the database, and
+will not run again without the --force option.
+TEXT
+               );
+
+               $this->addOption(
+                       'mode',
+                       '"add" empty categories with description pages, "remove" empty categories '
+                       . 'without description pages, or "both"',
+                       false,
+                       true
+               );
+               $this->addOption(
+                       'begin',
+                       'Only do categories whose names are alphabetically after the provided name',
+                       false,
+                       true
+               );
+               $this->addOption(
+                       'throttle',
+                       'Wait this many milliseconds after each batch. Default: 0',
+                       false,
+                       true
+               );
+       }
+
+       protected function getUpdateKey() {
+               return 'cleanup empty categories';
+       }
+
+       protected function doDBUpdates() {
+               $mode = $this->getOption( 'mode', 'both' );
+               $begin = $this->getOption( 'begin', '' );
+               $throttle = $this->getOption( 'throttle', 0 );
+
+               if ( !in_array( $mode, [ 'add', 'remove', 'both' ] ) ) {
+                       $this->output( "--mode must be 'add', 'remove', or 'both'.\n" );
+                       return false;
+               }
+
+               $dbw = $this->getDB( DB_MASTER );
+
+               $throttle = intval( $throttle );
+
+               if ( $mode === 'add' || $mode === 'both' ) {
+                       if ( $begin !== '' ) {
+                               $where = [ 'page_title > ' . $dbw->addQuotes( $begin ) ];
+                       } else {
+                               $where = [];
+                       }
+
+                       $this->output( "Adding empty categories with description pages...\n" );
+                       while ( true ) {
+                               # Find which category to update
+                               $rows = $dbw->select(
+                                       [ 'page', 'category' ],
+                                       'page_title',
+                                       array_merge( $where, [
+                                               'page_namespace' => NS_CATEGORY,
+                                               'cat_title' => null,
+                                       ] ),
+                                       __METHOD__,
+                                       [
+                                               'ORDER BY' => 'page_title',
+                                               'LIMIT' => $this->mBatchSize,
+                                       ],
+                                       [
+                                               'category' => [ 'LEFT JOIN', 'page_title = cat_title' ],
+                                       ]
+                               );
+                               if ( !$rows || $rows->numRows() <= 0 ) {
+                                       # Done, hopefully.
+                                       break;
+                               }
+
+                               foreach ( $rows as $row ) {
+                                       $name = $row->page_title;
+                                       $where = [ 'page_title > ' . $dbw->addQuotes( $name ) ];
+
+                                       # Use the row to update the category count
+                                       $cat = Category::newFromName( $name );
+                                       if ( !is_object( $cat ) ) {
+                                               $this->output( "The category named $name is not valid?!\n" );
+                                       } else {
+                                               $cat->refreshCounts();
+                                       }
+                               }
+                               $this->output( "--mode=$mode --begin=$name\n" );
+
+                               wfWaitForSlaves();
+                               usleep( $throttle * 1000 );
+                       }
+
+                       $begin = '';
+               }
+
+               if ( $mode === 'remove' || $mode === 'both' ) {
+                       if ( $begin !== '' ) {
+                               $where = [ 'cat_title > ' . $dbw->addQuotes( $begin ) ];
+                       } else {
+                               $where = [];
+                       }
+                       $i = 0;
+
+                       $this->output( "Removing empty categories without description pages...\n" );
+                       while ( true ) {
+                               # Find which category to update
+                               $rows = $dbw->select(
+                                       [ 'category', 'page' ],
+                                       'cat_title',
+                                       array_merge( $where, [
+                                               'page_title' => null,
+                                               'cat_pages' => 0,
+                                       ] ),
+                                       __METHOD__,
+                                       [
+                                               'ORDER BY' => 'cat_title',
+                                               'LIMIT' => $this->mBatchSize,
+                                       ],
+                                       [
+                                               'page' => [ 'LEFT JOIN', [
+                                                       'page_namespace' => NS_CATEGORY, 'page_title = cat_title'
+                                               ] ],
+                                       ]
+                               );
+                               if ( !$rows || $rows->numRows() <= 0 ) {
+                                       # Done, hopefully.
+                                       break;
+                               }
+                               foreach ( $rows as $row ) {
+                                       $name = $row->cat_title;
+                                       $where = [ 'cat_title > ' . $dbw->addQuotes( $name ) ];
+
+                                       # Use the row to update the category count
+                                       $cat = Category::newFromName( $name );
+                                       if ( !is_object( $cat ) ) {
+                                               $this->output( "The category named $name is not valid?!\n" );
+                                       } else {
+                                               $cat->refreshCounts();
+                                       }
+                               }
+
+                               $this->output( "--mode=remove --begin=$name\n" );
+
+                               wfWaitForSlaves();
+                               usleep( $throttle * 1000 );
+                       }
+               }
+
+               $this->output( "Category cleanup complete.\n" );
+
+               return true;
+       }
+}
+
+$maintClass = 'CleanupEmptyCategories';
+require_once RUN_MAINTENANCE_IF_MAIN;
index d07a8d4..af05a81 100644 (file)
@@ -54,7 +54,7 @@ class DeleteArchivedFiles extends Maintenance {
                $this->output( "Searching for and deleting archived files...\n" );
                $res = $dbw->select(
                        'filearchive',
-                       [ 'fa_id', 'fa_storage_group', 'fa_storage_key', 'fa_sha1' ],
+                       [ 'fa_id', 'fa_storage_group', 'fa_storage_key', 'fa_sha1', 'fa_name' ],
                        '',
                        __METHOD__
                );
@@ -67,9 +67,19 @@ class DeleteArchivedFiles extends Maintenance {
                                continue;
                        }
 
+                       /** @var LocalFile $file */
+                       $file = $repo->newFile( $row->fa_name );
+                       try {
+                               $file->lock();
+                       } catch ( LocalFileLockError $e ) {
+                               $this->error( "Could not acquire lock on '{$row->fa_name}', skipping\n" );
+                               continue;
+                       }
+
                        $group = $row->fa_storage_group;
                        $id = $row->fa_id;
-                       $path = $repo->getZonePath( 'deleted' ) . '/' . $repo->getDeletedHashPath( $key ) . $key;
+                       $path = $repo->getZonePath( 'deleted' ) .
+                               '/' . $repo->getDeletedHashPath( $key ) . $key;
                        if ( isset( $row->fa_sha1 ) ) {
                                $sha1 = $row->fa_sha1;
                        } else {
@@ -96,6 +106,7 @@ class DeleteArchivedFiles extends Maintenance {
                                $this->output( "Notice - file '$key' is still in use\n" );
                        } elseif ( !$repo->quickPurge( $path ) ) {
                                $this->output( "Unable to remove file $path, skipping\n" );
+                               $file->unlock();
                                continue; // don't delete even with --force
                        } else {
                                $needForce = false;
@@ -105,12 +116,14 @@ class DeleteArchivedFiles extends Maintenance {
                                if ( $this->hasOption( 'force' ) ) {
                                        $this->output( "Got --force, deleting DB entry\n" );
                                } else {
+                                       $file->unlock();
                                        continue;
                                }
                        }
 
                        $count++;
                        $dbw->delete( 'filearchive', [ 'fa_id' => $id ], __METHOD__ );
+                       $file->unlock();
                }
 
                $this->commitTransaction( $dbw, __METHOD__ );
index 631d2a7..068ee8c 100644 (file)
@@ -65,7 +65,7 @@
                                        "mw.Upload*",
                                        "mw.ForeignUpload",
                                        "mw.ForeignStructuredUpload*",
-                                       "mw.GallerySlider"
+                                       "mw.GallerySlideshow"
                                ]
                        },
                        {
index 05f091f..bced265 100644 (file)
@@ -201,7 +201,7 @@ U+090C1郁|U+090C1郁|U+09B31鬱|
 U+0915D酝|U+0919E醞|U+09196醖|
 U+09170酰|U+09170酰|U+091AF醯|
 U+09178酸|U+09178酸|U+075E0痠|
-U+091C7采|U+091C7采|U+063A1採|U+057F0埰|
+U+091C7采|U+091C7采|U+063A1採|U+05BC0寀|
 U+091CC里|U+091CC里|U+088E1裡|U+088CF裏|
 U+0949F钟|U+0937E鍾|U+09418鐘|
 U+094A9钩|U+0920E鈎|U+09264鉤|
index a81422d..bae5fd8 100644 (file)
 伏著 伏着
 視著 视着
 視著名      视著名
+視著作      视著作
+視著者      视著者
+視著稱      视著称
 蓋著 盖着
 蓋著名      盖著名
 蓋著稱      盖著称
 功能變數名稱     域名
 音效卡      声卡
 字型大小   字号
-字型檔      字库
 欄位 字段
 非同步      异步
 匯流排      总线
index 7bd993f..5ec6e34 100644 (file)
 电视里      電視裏
 公寓里      公寓裏
 窝里斗      窩裏鬥
+镇里 鎮裏
 苑裡 苑裡
 霄裡 霄裡
 岸裡 岸裡
 伏著 伏着
 視著 視着
 視著名      視著名
+視著作      視著作
+視著者      視著者
+視著稱      視著稱
 蓋著 蓋着
 蓋著名      蓋著名
 蓋著稱      蓋著稱
index 9674aae..8618a93 100644 (file)
 偵蒐 侦搜
 情蒐 情搜
 蘋果 苹果
+蘋婆 苹婆
 於之莹      於之莹
 陆徵祥      陆徵祥
 瞭臺 瞭台
index b840408..59219ae 100644 (file)
 光盘 光碟
 光驱 光碟機
 声卡 音效卡
-字库 字型檔
 字段 欄位
 存盘 存檔
 控件 控制項
index 83a7a54..8fb4198 100644 (file)
 复苏 復甦
 苹果 蘋果
 苹果干      蘋果乾
+苹婆 蘋婆
 龜山庄      龜山庄
 寶山庄      寶山庄
 員山庄      員山庄
index 56a5e21..463c126 100644 (file)
 皺彆
 一彆頭
 并州
+併力
 ,並力
-,并力攻
 ,并力討
+兼併
 併兼
 併骨
 併網
 錢穀
 息穀
 殖穀
-川穀
 曬穀
 臧穀亡羊
 種穀
 乾姐
 乾紅葡萄酒
 乾白葡萄酒
+抽乾
+排乾
+排幹部
+吸乾
 楨幹
 新幹縣
 誰幹的
 鍥而不捨
 稜登
 繃扒弔拷
-不弔
+不弔
 不通弔慶
 陪弔
 盆弔
 公寓里弄
 村裡的
 村裡有
+鎮裡
 裏白 #植物常用名
 烏蘇里 #分詞用
 首發
index 12cfed8..48b2250 100644 (file)
@@ -336,9 +336,9 @@ CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp);
 CREATE INDEX /*i*/cl_collation_ext ON /*_*/categorylinks (cl_collation, cl_to, cl_type, cl_from);
 
 --
--- Track all existing categories.  Something is a category if 1) it has an en-
--- try somewhere in categorylinks, or 2) it once did.  Categories might not
--- have corresponding pages, so they need to be tracked separately.
+-- Track all existing categories. Something is a category if 1) it has an entry
+-- somewhere in categorylinks, or 2) it has a description page. Categories
+-- might not have corresponding pages, so they need to be tracked separately.
 --
 CREATE TABLE /*_*/category (
   -- Primary key
index b67bc36..38556ed 100644 (file)
@@ -48,7 +48,7 @@ class RebuildFileCache extends Maintenance {
        }
 
        public function execute() {
-               global $wgUseFileCache, $wgReadOnly, $wgContentNamespaces, $wgRequestTime;
+               global $wgUseFileCache, $wgReadOnly, $wgRequestTime;
                global $wgOut;
                if ( !$wgUseFileCache ) {
                        $this->error( "Nothing to do -- \$wgUseFileCache is disabled.", true );
@@ -94,7 +94,7 @@ class RebuildFileCache extends Maintenance {
                while ( $blockEnd <= $end ) {
                        // Get the pages
                        $res = $dbr->select( 'page', [ 'page_namespace', 'page_title', 'page_id' ],
-                               [ 'page_namespace' => $wgContentNamespaces,
+                               [ 'page_namespace' => MWNamespace::getContentNamespaces(),
                                        "page_id BETWEEN $blockStart AND $blockEnd" ],
                                [ 'ORDER BY' => 'page_id ASC', 'USE INDEX' => 'PRIMARY' ]
                        );
index 89aeb9c..9c9bdfb 100644 (file)
@@ -623,9 +623,9 @@ CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp);
 CREATE INDEX /*i*/cl_collation_ext ON /*_*/categorylinks (cl_collation, cl_to, cl_type, cl_from);
 
 --
--- Track all existing categories.  Something is a category if 1) it has an en-
--- try somewhere in categorylinks, or 2) it once did.  Categories might not
--- have corresponding pages, so they need to be tracked separately.
+-- Track all existing categories. Something is a category if 1) it has an entry
+-- somewhere in categorylinks, or 2) it has a description page. Categories
+-- might not have corresponding pages, so they need to be tracked separately.
 --
 CREATE TABLE /*_*/category (
   -- Primary key
diff --git a/maintenance/updateExtensionJsonSchema.php b/maintenance/updateExtensionJsonSchema.php
new file mode 100644 (file)
index 0000000..427769f
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+require_once __DIR__ . '/Maintenance.php';
+
+class UpdateExtensionJsonSchema extends Maintenance {
+
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Updates extension.json files to the latest manifest_version' );
+               $this->addArg( 'path', 'Location to the extension.json or skin.json you wish to convert',
+                       /* $required = */ true );
+       }
+
+       public function execute() {
+               $filename = $this->getArg( 0 );
+               if ( !is_readable( $filename ) ) {
+                       $this->error( "Error: Unable to read $filename", 1 );
+               }
+
+               $json = FormatJson::decode( file_get_contents( $filename ), true );
+               if ( $json === null ) {
+                       $this->error( "Error: Invalid JSON", 1 );
+               }
+
+               if ( !isset( $json['manifest_version'] ) ) {
+                       $json['manifest_version'] = 1;
+               }
+
+               if ( $json['manifest_version'] == ExtensionRegistry::MANIFEST_VERSION ) {
+                       $this->output( "Already at the latest version: {$json['manifest_version']}\n" );
+                       return;
+               }
+
+               while ( $json['manifest_version'] !== ExtensionRegistry::MANIFEST_VERSION ) {
+                       $json['manifest_version'] += 1;
+                       $func = "updateTo{$json['manifest_version']}";
+                       $this->$func( $json );
+               }
+
+               file_put_contents( $filename, FormatJson::encode( $json, "\t", FormatJson::ALL_OK ) . "\n" );
+               $this->output( "Updated to {$json['manifest_version']}...\n" );
+       }
+
+       protected function updateTo2( &$json ) {
+               if ( isset( $json['config'] ) ) {
+                       $config = $json['config'];
+                       $json['config'] = [];
+                       if ( isset( $config['_prefix'] ) ) {
+                               $json = wfArrayInsertAfter( $json, [
+                                       'config_prefix' => $config['_prefix']
+                               ], 'config' );
+                               unset( $config['_prefix'] );
+                       }
+
+                       foreach ( $config as $name => $value ) {
+                               if ( $name[0] !== '@' ) {
+                                       $json['config'][$name] = [ 'value' => $value ];
+                                       if ( isset( $value[ExtensionRegistry::MERGE_STRATEGY] ) ) {
+                                               $json['config'][$name]['merge_strategy'] = $value[ExtensionRegistry::MERGE_STRATEGY];
+                                               unset( $value[ExtensionRegistry::MERGE_STRATEGY] );
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+$maintClass = 'UpdateExtensionJsonSchema';
+require_once RUN_MAINTENANCE_IF_MAIN;
index d96dcf9..780e049 100644 (file)
     "grunt-contrib-watch": "1.0.0",
     "grunt-jscs": "2.8.0",
     "grunt-jsonlint": "1.0.7",
-    "grunt-karma": "0.12.2",
+    "grunt-karma": "2.0.0",
     "grunt-stylelint": "0.4.0",
-    "karma": "0.13.22",
-    "karma-chrome-launcher": "0.2.2",
-    "karma-firefox-launcher": "0.1.7",
-    "karma-qunit": "0.1.9",
+    "karma": "1.1.0",
+    "karma-chrome-launcher": "1.0.1",
+    "karma-firefox-launcher": "1.0.0",
+    "karma-qunit": "1.0.0",
     "qunitjs": "1.22.0",
     "stylelint-config-wikimedia": "0.2.2"
   }
index 1805c84..e838a53 100644 (file)
@@ -948,7 +948,7 @@ return [
        ],
        'mediawiki.content.json' => [
                'position' => 'top',
-               'styles' => 'resources/src/mediawiki/mediawiki.content.json.css',
+               'styles' => 'resources/src/mediawiki/mediawiki.content.json.less',
        ],
        'mediawiki.confirmCloseWindow' => [
                'scripts' => [
@@ -1297,7 +1297,6 @@ return [
                        'filename-thumb-name',
                        'badfilename',
                        'protectedpagetext',
-                       'api-error-blacklisted', // HACK
                ],
        ],
        'mediawiki.ForeignStructuredUpload.BookletLayout' => [
@@ -1656,8 +1655,8 @@ return [
                'position' => 'top',
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'mediawiki.page.gallery.slider' => [
-               'scripts' => 'resources/src/mediawiki/page/gallery-slider.js',
+       'mediawiki.page.gallery.slideshow' => [
+               'scripts' => 'resources/src/mediawiki/page/gallery-slideshow.js',
                'position' => 'top',
                'dependencies' => [
                        'mediawiki.api',
index 026bbb3..a34432f 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:08Z
+ * Date: 2016-07-12T20:26:03Z
  */
 ( function ( OO ) {
 
@@ -27,6 +27,15 @@ OO.ui.ApexTheme = function OoUiApexTheme() {
 
 OO.inheritClass( OO.ui.ApexTheme, OO.ui.Theme );
 
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ApexTheme.prototype.getDialogTransitionDuration = function () {
+       return 250;
+};
+
 /* Instantiation */
 
 OO.ui.theme = new OO.ui.ApexTheme();
index fa5ec0a..152d444 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:11Z
+ * Date: 2016-07-12T20:26:07Z
  */
 .oo-ui-element-hidden {
        display: none !important;
 .oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
        cursor: default;
 }
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       z-index: 2;
+}
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
 }
 .oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
        padding: 0.5em 0.75em;
-       line-height: 1.5em;
+       line-height: 1.5;
 }
 .oo-ui-fieldLayout:last-child {
        margin-bottom: 0;
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
        padding: 0.5em 0.75em;
-       line-height: 1.5em;
+       line-height: 1.5;
 }
 .oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
 .oo-ui-fieldsetLayout + .oo-ui-formLayout {
index 03380b2..a191804 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:11Z
+ * Date: 2016-07-12T20:26:07Z
  */
 .oo-ui-element-hidden {
        display: none !important;
 .oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
        cursor: default;
 }
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       z-index: 2;
+}
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
@@ -49,6 +54,7 @@
        text-decoration: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button:focus {
+       border-radius: 2px;
        outline: 0;
 }
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
 }
 .oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       line-height: 1.2em;
+       line-height: 1.2;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
        position: absolute;
 }
 .oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
        padding: 0.5em 0.75em;
-       line-height: 1.5em;
+       line-height: 1.5;
 }
 .oo-ui-fieldLayout:last-child {
        margin-bottom: 0;
 .oo-ui-fieldLayout-messages .oo-ui-labelWidget {
        display: table-cell;
        padding: 0;
-       line-height: 1.875em;
+       line-height: 1.875;
        vertical-align: middle;
 }
 .oo-ui-actionFieldLayout {
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
        padding: 0.5em 0.75em;
-       line-height: 1.5em;
+       line-height: 1.5;
 }
 .oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
 .oo-ui-fieldsetLayout + .oo-ui-formLayout {
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
        padding-left: 2em;
-       line-height: 1.8em;
+       line-height: 1.8;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
        left: 0;
        background-color: #eeeeee;
 }
 .oo-ui-optionWidget .oo-ui-labelElement-label {
-       line-height: 1.5em;
+       line-height: 1.5;
 }
 .oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected,
 .oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed,
 .oo-ui-iconWidget {
        display: inline-block;
        vertical-align: middle;
-       line-height: 2.5em;
+       line-height: 2.5;
 }
 .oo-ui-iconWidget.oo-ui-widget-disabled {
        opacity: 0.2;
 .oo-ui-indicatorWidget {
        display: inline-block;
        vertical-align: middle;
-       line-height: 2.5em;
+       line-height: 2.5;
        margin: 0.46875em;
 }
 .oo-ui-indicatorWidget.oo-ui-widget-disabled {
        border-radius: 0;
        margin-left: -1px;
 }
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button:focus {
-       z-index: 2;
-}
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
        border-bottom-left-radius: 2px;
        border-top-left-radius: 2px;
        padding: 0.25em 0;
 }
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body .oo-ui-labelElement-label {
-       line-height: 1.5em;
+       line-height: 1.5;
 }
 .oo-ui-dropdownInputWidget {
        position: relative;
        padding: 0.25em 0;
 }
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body .oo-ui-labelElement-label {
-       line-height: 1.5em;
+       line-height: 1.5;
 }
 .oo-ui-textInputWidget {
        position: relative;
        border-radius: 2px;
 }
 .oo-ui-textInputWidget textarea {
-       line-height: 1.275em;
+       line-height: 1.275;
 }
 .oo-ui-textInputWidget .oo-ui-pendingElement-pending {
        background-color: transparent;
        border-color: #cccccc;
        box-shadow: inset 0 0 0 0.1em #cccccc;
 }
+.oo-ui-textInputWidget.oo-ui-widget-enabled :-moz-placeholder {
+       color: #595959;
+       opacity: 1;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled ::-moz-placeholder {
+       color: #595959;
+       opacity: 1;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled :-ms-input-placeholder {
+       color: #595959;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled ::-webkit-input-placeholder {
+       color: #595959;
+}
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
        border-color: #ff0000;
 }
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
        padding: 0.4em;
-       line-height: 1.5em;
+       line-height: 1.5;
        color: #888888;
 }
 .oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
        overflow: hidden;
 }
 .oo-ui-multioptionWidget .oo-ui-labelElement-label {
-       line-height: 1.5em;
+       line-height: 1.5;
 }
 .oo-ui-multioptionWidget.oo-ui-widget-disabled {
        color: #cccccc;
index e230a49..2a1427b 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:08Z
+ * Date: 2016-07-12T20:26:03Z
  */
 ( function ( OO ) {
 
@@ -1634,6 +1634,18 @@ OO.ui.Theme.prototype.updateElementClasses = function ( element ) {
                .addClass( classes.on.join( ' ' ) );
 };
 
+/**
+ * Get the transition duration in milliseconds for dialogs opening/closing
+ *
+ * The dialog should be fully rendered this many milliseconds after the
+ * ready process has executed.
+ *
+ * @return {number} Transition duration in milliseconds
+ */
+OO.ui.Theme.prototype.getDialogTransitionDuration = function () {
+       return 0;
+};
+
 /**
  * The TabIndexedElement class is an attribute mixin used to add additional functionality to an
  * element created by another class. The mixin provides a ‘tabIndex’ property, which specifies the
@@ -3727,6 +3739,7 @@ OO.ui.IndicatorWidget.static.tagName = 'span';
  * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.TitledElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -7580,7 +7593,7 @@ OO.ui.InputWidget.prototype.restorePreInfuseState = function ( state ) {
  * ButtonInputWidget is used to submit HTML forms and is intended to be used within
  * a OO.ui.FormLayout. If you do not need the button to work with HTML forms, you probably
  * want to use OO.ui.ButtonWidget instead. Button input widgets can be rendered as either an
- * HTML `<button/>` (the default) or an HTML `<input/>` tags. See the
+ * HTML `<button>` (the default) or an HTML `<input>` tags. See the
  * [OOjs UI documentation on MediaWiki] [1] for more information.
  *
  *     @example
@@ -7605,8 +7618,8 @@ OO.ui.InputWidget.prototype.restorePreInfuseState = function ( state ) {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {string} [type='button'] The value of the HTML `'type'` attribute: 'button', 'submit' or 'reset'.
- * @cfg {boolean} [useInputTag=false] Use an `<input/>` tag instead of a `<button/>` tag, the default.
- *  Widgets configured to be an `<input/>` do not support {@link #icon icons} and {@link #indicator indicators},
+ * @cfg {boolean} [useInputTag=false] Use an `<input>` tag instead of a `<button>` tag, the default.
+ *  Widgets configured to be an `<input>` do not support {@link #icon icons} and {@link #indicator indicators},
  *  non-plaintext {@link #label labels}, or {@link #value values}. In general, useInputTag should only
  *  be set to `true` when there’s need to support IE 6 in a form with multiple buttons.
  */
@@ -7671,7 +7684,7 @@ OO.ui.ButtonInputWidget.prototype.getInputElement = function ( config ) {
 /**
  * Set label value.
  *
- * If #useInputTag is `true`, the label is set as the `value` of the `<input/>` tag.
+ * If #useInputTag is `true`, the label is set as the `value` of the `<input>` tag.
  *
  * @param {jQuery|string|Function|null} label Label nodes, text, a function that returns nodes or
  *  text, or `null` for no label
@@ -7697,7 +7710,7 @@ OO.ui.ButtonInputWidget.prototype.setLabel = function ( label ) {
 /**
  * Set the value of the input.
  *
- * This method is disabled for button inputs configured as {@link #useInputTag <input/> tags}, as
+ * This method is disabled for button inputs configured as {@link #useInputTag <input> tags}, as
  * they do not support {@link #value values}.
  *
  * @param {string} value New value
index 15d4d44..d0de9df 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:08Z
+ * Date: 2016-07-12T20:26:03Z
  */
 ( function ( OO ) {
 
@@ -72,6 +72,13 @@ OO.ui.MediaWikiTheme.prototype.getElementClasses = function ( element ) {
        return classes;
 };
 
+/**
+ * @inheritdoc
+ */
+OO.ui.MediaWikiTheme.prototype.getDialogTransitionDuration = function () {
+       return 250;
+};
+
 /* Instantiation */
 
 OO.ui.theme = new OO.ui.MediaWikiTheme();
index cb5eeda..e758f82 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:11Z
+ * Date: 2016-07-12T20:26:07Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
        clear: both;
 }
 .oo-ui-toolbar-bar {
-       line-height: 1em;
+       line-height: 1;
        position: relative;
 }
 .oo-ui-toolbar-actions {
index 09730d4..0c007bb 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:11Z
+ * Date: 2016-07-12T20:26:07Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
@@ -33,7 +33,7 @@
        width: 1.875em;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup.oo-ui-labelElement > .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.1em;
+       line-height: 2.1;
 }
 .oo-ui-toolGroup {
        display: inline-block;
@@ -93,7 +93,7 @@
        width: 1.875em;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2.1em;
+       line-height: 2.1;
        padding: 0 0.4em;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover {
        min-width: 3.75em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.6em;
+       line-height: 2.6;
        margin: 0 1em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
        left: 0;
 }
 .oo-ui-popupToolGroup-header {
-       line-height: 2.6em;
+       line-height: 2.6;
        margin: 0 0.6em;
        font-weight: bold;
 }
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2em;
+       line-height: 2;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
        color: #888888;
        clear: both;
 }
 .oo-ui-toolbar-bar {
-       line-height: 1em;
+       line-height: 1;
        position: relative;
 }
 .oo-ui-toolbar-actions {
index 97a8fc9..66473ff 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:08Z
+ * Date: 2016-07-12T20:26:03Z
  */
 ( function ( OO ) {
 
@@ -1292,24 +1292,26 @@ OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
        var i, len, item, name, tool,
                names = [];
 
-       if ( collection === '*' ) {
-               for ( name in this.registry ) {
-                       tool = this.registry[ name ];
-                       if (
-                               // Only add tools by group name when auto-add is enabled
-                               tool.static.autoAddToCatchall &&
-                               // Exclude already used tools
-                               ( !used || !used[ name ] )
-                       ) {
-                               names.push( name );
-                               if ( used ) {
-                                       used[ name ] = true;
+       collection = !Array.isArray( collection ) ? [ collection ] : collection;
+
+       for ( i = 0, len = collection.length; i < len; i++ ) {
+               item = collection[ i ];
+               if ( item === '*' ) {
+                       for ( name in this.registry ) {
+                               tool = this.registry[ name ];
+                               if (
+                                       // Only add tools by group name when auto-add is enabled
+                                       tool.static.autoAddToCatchall &&
+                                       // Exclude already used tools
+                                       ( !used || !used[ name ] )
+                               ) {
+                                       names.push( name );
+                                       if ( used ) {
+                                               used[ name ] = true;
+                                       }
                                }
                        }
-               }
-       } else if ( Array.isArray( collection ) ) {
-               for ( i = 0, len = collection.length; i < len; i++ ) {
-                       item = collection[ i ];
+               } else {
                        // Allow plain strings as shorthand for named tools
                        if ( typeof item === 'string' ) {
                                item = { name: item };
index 68156c7..e83cce5 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:11Z
+ * Date: 2016-07-12T20:26:07Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
index 048e732..375a478 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:11Z
+ * Date: 2016-07-12T20:26:07Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
           -moz-box-sizing: border-box;
                box-sizing: border-box;
        display: block;
-       line-height: 2.3em;
+       line-height: 2.3;
        margin: 0;
        overflow: hidden;
        white-space: nowrap;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input {
        border: 0;
-       line-height: 1.675em;
+       line-height: 1.675;
        margin: 0 0 0 0.2em;
        padding: 0;
        font-size: inherit;
                box-sizing: border-box;
        vertical-align: middle;
        height: 1.7em;
-       line-height: 1.7em;
+       line-height: 1.7;
        background-color: #eeeeee;
        color: #555555;
        margin: 0.1em;
index c4486d3..8d93b80 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:08Z
+ * Date: 2016-07-12T20:26:03Z
  */
 ( function ( OO ) {
 
@@ -1426,10 +1426,12 @@ OO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem )
                for ( i = 0, len = items.length; i < len; i++ ) {
                        if ( !selectedItem || selectedItem !== items[ i ] ) {
                                items[ i ].$element.addClass( 'oo-ui-element-hidden' );
+                               items[ i ].$element.attr( 'aria-hidden', 'true' );
                        }
                }
                if ( selectedItem ) {
                        selectedItem.$element.removeClass( 'oo-ui-element-hidden' );
+                       selectedItem.$element.removeAttr( 'aria-hidden' );
                }
        }
 };
@@ -1553,6 +1555,7 @@ OO.ui.MenuLayout.prototype.toggleMenu = function ( showMenu ) {
                this.$element
                        .toggleClass( 'oo-ui-menuLayout-showMenu', this.showMenu )
                        .toggleClass( 'oo-ui-menuLayout-hideMenu', !this.showMenu );
+               this.$menu.attr( 'aria-hidden', this.showMenu ? 'false' : 'true' );
        }
 
        return this;
@@ -3692,13 +3695,17 @@ OO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.IconElement );
 
 /**
  * Construct a OO.ui.CapsuleItemWidget (or a subclass thereof) from given label and data.
+ * May return `null` if the given label and data are not valid.
  *
  * @protected
  * @param {Mixed} data Custom data of any type.
  * @param {string} label The label text.
- * @return {OO.ui.CapsuleItemWidget}
+ * @return {OO.ui.CapsuleItemWidget|null}
  */
 OO.ui.CapsuleMultiselectWidget.prototype.createItemWidget = function ( data, label ) {
+       if ( label === '' ) {
+               return null;
+       }
        return new OO.ui.CapsuleItemWidget( { data: data, label: label } );
 };
 
@@ -3748,7 +3755,9 @@ OO.ui.CapsuleMultiselectWidget.prototype.setItemsFromData = function ( datas ) {
                if ( !item ) {
                        item = widget.createItemWidget( data, label );
                }
-               widget.addItems( [ item ], i );
+               if ( item ) {
+                       widget.addItems( [ item ], i );
+               }
        } );
 
        if ( items.length ) {
@@ -3776,9 +3785,12 @@ OO.ui.CapsuleMultiselectWidget.prototype.addItemsFromData = function ( datas ) {
                if ( !widget.getItemFromData( data ) ) {
                        item = menu.getItemFromData( data );
                        if ( item ) {
-                               items.push( widget.createItemWidget( data, item.label ) );
+                               item = widget.createItemWidget( data, item.label );
                        } else if ( widget.allowArbitrary ) {
-                               items.push( widget.createItemWidget( data, String( data ) ) );
+                               item = widget.createItemWidget( data, String( data ) );
+                       }
+                       if ( item ) {
+                               items.push( item );
                        }
                }
        } );
@@ -3797,13 +3809,15 @@ OO.ui.CapsuleMultiselectWidget.prototype.addItemsFromData = function ( datas ) {
  * @return {boolean} Whether the item was added or not
  */
 OO.ui.CapsuleMultiselectWidget.prototype.addItemFromLabel = function ( label ) {
-       var item = this.menu.getItemFromLabel( label, true );
+       var item, items;
+       item = this.menu.getItemFromLabel( label, true );
        if ( item ) {
                this.addItemsFromData( [ item.data ] );
                return true;
-       } else if ( this.allowArbitrary && this.$input.val().trim() !== '' ) {
+       } else if ( this.allowArbitrary ) {
+               items = this.getItems();
                this.addItemsFromData( [ label ] );
-               return true;
+               return !OO.compare( this.getItems(), items );
        }
        return false;
 };
index b55dd25..66cd523 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:11Z
+ * Date: 2016-07-12T20:26:07Z
  */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
        background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
index 727e874..30bf1c4 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:11Z
+ * Date: 2016-07-12T20:26:07Z
  */
 .oo-ui-window {
        background: transparent;
 }
 .oo-ui-messageDialog-title {
        font-size: 1.5em;
-       line-height: 1em;
+       line-height: 1;
        color: #000000;
 }
 .oo-ui-messageDialog-message {
        font-size: 0.9em;
-       line-height: 1.25em;
+       line-height: 1.25;
        color: #555555;
 }
 .oo-ui-messageDialog-message-verbose {
        font-size: 1.1em;
-       line-height: 1.5em;
+       line-height: 1.5;
        text-align: left;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
        margin-right: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       text-align: center;
        line-height: 3.4;
+       text-align: center;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
        background-color: rgba(0, 0, 0, 0.05);
index 8234b6d..6446302 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.5
+ * OOjs UI v0.17.6
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-06-29T13:27:08Z
+ * Date: 2016-07-12T20:26:03Z
  */
 ( function ( OO ) {
 
@@ -2135,10 +2135,18 @@ OO.ui.Window.prototype.initialize = function () {
  * @param {jQuery.Event} event Focus event
  */
 OO.ui.Window.prototype.onFocusTrapFocused = function ( event ) {
-       if ( this.$focusTrapBefore.is( event.target ) ) {
-               OO.ui.findFocusable( this.$content, true ).focus();
+       var backwards = this.$focusTrapBefore.is( event.target ),
+               element = OO.ui.findFocusable( this.$content, backwards );
+       if ( element ) {
+               // There's a focusable element inside the content, at the front or
+               // back depending on which focus trap we hit; select it.
+               element.focus();
        } else {
-               // this.$content is the part of the focus cycle, and is the first focusable element
+               // There's nothing focusable inside the content. As a fallback,
+               // this.$content is focusable, and focusing it will keep our focus
+               // properly trapped. It's not a *meaningful* focus, since it's just
+               // the content-div for the Window, but it's better than letting focus
+               // escape into the page.
                this.$content.focus();
        }
 };
@@ -2512,11 +2520,10 @@ OO.ui.Dialog.prototype.getSetupProcess = function ( data ) {
        return OO.ui.Dialog.parent.prototype.getSetupProcess.call( this, data )
                .next( function () {
                        var config = this.constructor.static,
-                               actions = data.actions !== undefined ? data.actions : config.actions;
+                               actions = data.actions !== undefined ? data.actions : config.actions,
+                               title = data.title !== undefined ? data.title : config.title;
 
-                       this.title.setLabel(
-                               data.title !== undefined ? data.title : this.constructor.static.title
-                       );
+                       this.title.setLabel( title ).setTitle( title );
                        this.actions.add( this.getActionWidgets( actions ) );
 
                        this.$element.on( 'keydown', this.onDialogKeyDownHandler );
index e881d7c..a9943cc 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/flag-rtl.png and b/resources/lib/oojs-ui/themes/apex/images/icons/flag-rtl.png differ
index 0f7e7ce..397a3da 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M11 6.5V5c1.4-1.5 5.2-1.2 6 0V4h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V13c-1.2 1.5-4.3 1.2-5 0V6c.7.7 2.7.9 4 .5z"/>
-</svg>
+       <path d="M10.3 7.5V6c1.4-1.5 5.2-1.2 6 0V5h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V14c-1.2 1.5-4.3 1.2-5 0V7c.7.7 2.7.9 4 .5z"/>
+</svg>
\ No newline at end of file
index 033adde..780cb87 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.png and b/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.png differ
index 516a3ea..4bbd61c 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M18 2L2.03 17.97l.97 1 4-4V19h1v-5.03l2.688-2.69c.81-.02 1.645.053 2.312.22V13c1.2 1.5 4.3 1.2 5 0V6c-.493.493-1.635.725-2.72.688L19 2.968zM7 4v7.03l6.438-6.436C11.778 3.61 8.71 3.934 8 5V4z"/>
-</svg>
+       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
+</svg>
\ No newline at end of file
index fca73fd..fa3696a 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.png and b/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.png differ
index 8ed159e..5d94425 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M7 2l-1 .97 3.72 3.717C8.634 6.727 7.492 6.494 7 6v7c.7 1.2 3.8 1.5 5 0v-1.5c.667-.167 1.5-.24 2.313-.22L17 13.97V19h1v-4.03l4 4 .97-1zm7.22 2c-.952-.03-1.932.163-2.658.594L18 11.03V4h-1v1c-.4-.6-1.556-.963-2.78-1z"/>
-</svg>
+       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
+</svg>
\ No newline at end of file
index e0b8859..159bdb9 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl-invert.png differ
index 3946c4a..dbc78c6 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
-    <path d="M11 6.5V5c1.4-1.5 5.2-1.2 6 0V4h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V13c-1.2 1.5-4.3 1.2-5 0V6c.7.7 2.7.9 4 .5z"/>
-</svg>
+       <path d="M10.3 7.5V6c1.4-1.5 5.2-1.2 6 0V5h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V14c-1.2 1.5-4.3 1.2-5 0V7c.7.7 2.7.9 4 .5z"/>
+</svg>
\ No newline at end of file
index e881d7c..a9943cc 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl.png differ
index 0f7e7ce..397a3da 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M11 6.5V5c1.4-1.5 5.2-1.2 6 0V4h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V13c-1.2 1.5-4.3 1.2-5 0V6c.7.7 2.7.9 4 .5z"/>
-</svg>
+       <path d="M10.3 7.5V6c1.4-1.5 5.2-1.2 6 0V5h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V14c-1.2 1.5-4.3 1.2-5 0V7c.7.7 2.7.9 4 .5z"/>
+</svg>
\ No newline at end of file
index 4985911..8338017 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.png differ
index 0d074de..0614672 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
-    <path d="M18 2L2.03 17.97l.97 1 4-4V19h1v-5.03l2.688-2.69c.81-.02 1.645.053 2.312.22V13c1.2 1.5 4.3 1.2 5 0V6c-.493.493-1.635.725-2.72.688L19 2.968zM7 4v7.03l6.438-6.436C11.778 3.61 8.71 3.934 8 5V4z"/>
-</svg>
+       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
+</svg>
\ No newline at end of file
index 033adde..780cb87 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.png differ
index 516a3ea..4bbd61c 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M18 2L2.03 17.97l.97 1 4-4V19h1v-5.03l2.688-2.69c.81-.02 1.645.053 2.312.22V13c1.2 1.5 4.3 1.2 5 0V6c-.493.493-1.635.725-2.72.688L19 2.968zM7 4v7.03l6.438-6.436C11.778 3.61 8.71 3.934 8 5V4z"/>
-</svg>
+       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
+</svg>
\ No newline at end of file
index 4e1a6d1..4f9c3ad 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.png differ
index 0653df3..66a0c05 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
-    <path d="M7 2l-1 .97 3.72 3.717C8.634 6.727 7.492 6.494 7 6v7c.7 1.2 3.8 1.5 5 0v-1.5c.667-.167 1.5-.24 2.313-.22L17 13.97V19h1v-4.03l4 4 .97-1zm7.22 2c-.952-.03-1.932.163-2.658.594L18 11.03V4h-1v1c-.4-.6-1.556-.963-2.78-1z"/>
-</svg>
+       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
+</svg>
\ No newline at end of file
index fca73fd..fa3696a 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.png differ
index 8ed159e..5d94425 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M7 2l-1 .97 3.72 3.717C8.634 6.727 7.492 6.494 7 6v7c.7 1.2 3.8 1.5 5 0v-1.5c.667-.167 1.5-.24 2.313-.22L17 13.97V19h1v-4.03l4 4 .97-1zm7.22 2c-.952-.03-1.932.163-2.658.594L18 11.03V4h-1v1c-.4-.6-1.556-.963-2.78-1z"/>
-</svg>
+       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
+</svg>
\ No newline at end of file
index 4c74c3e..9cd13be 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/stop-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/stop-invert.png differ
index 8b49792..2d060f3 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
-    <path d="M12 6c3.9 0 7 3.1 7 7s-3.1 7-7 7-7-3.1-7-7 3.1-7 7-7m0-1c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm-3 5h6v6H9z"/>
+       <path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3 11.1H9v-6h6v6z"/>
 </svg>
index 12a1912..77dd75f 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/stop.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/stop.png differ
index aa25e3d..4631b85 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M12 6c3.9 0 7 3.1 7 7s-3.1 7-7 7-7-3.1-7-7 3.1-7 7-7m0-1c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm-3 5h6v6H9z"/>
+       <path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3 11.1H9v-6h6v6z"/>
 </svg>
index ce46de5..fc16377 100644 (file)
@@ -91,6 +91,13 @@ abbr[title],
        }
 }
 
+/* Comment portions of RC entries */
+span.comment {
+       font-style: italic;
+       unicode-bidi: -moz-isolate;
+       unicode-bidi: isolate;
+}
+
 /**
  * Add a bit of margin space between the preview and the toolbar.
  * This replaces the ugly <p><br /></p> we used to insert into the page source
index 85bf9f6..563db00 100644 (file)
@@ -253,3 +253,9 @@ div.tright {
 div.tleft {
        margin: .5em 1.4em 1.3em 0;
 }
+
+/* Hide elements that are marked as "empty" according to legacy Tidy rules
+ */
+.mw-empty-elt, .mw-empty-li {
+       display: none;
+}
diff --git a/resources/src/mediawiki.skinning/images/external link icons.svg b/resources/src/mediawiki.skinning/images/external link icons.svg
deleted file mode 100644 (file)
index 6a67993..0000000
+++ /dev/null
@@ -1,697 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="13"
-   height="110"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.48.5 r10040"
-   sodipodi:docname="external link icons.svg">
-  <defs
-     id="defs4" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="15.999999"
-     inkscape:cx="10.40536"
-     inkscape:cy="65.686256"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer5"
-     showgrid="true"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:window-width="1283"
-     inkscape:window-height="711"
-     inkscape:window-x="1790"
-     inkscape:window-y="-6"
-     inkscape:window-maximized="0">
-    <inkscape:grid
-       type="xygrid"
-       id="grid3246"
-       empspacing="4"
-       visible="true"
-       enabled="true"
-       snapvisiblegridlinesonly="true"
-       originx="0px"
-       originy="-27.999997px" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:groupmode="layer"
-     id="layer2"
-     inkscape:label="base"
-     style="display:none"
-     transform="translate(-505,-869.36218)">
-    <rect
-       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4646"
-       width="13"
-       height="12.999996"
-       x="505"
-       y="885.36218" />
-    <rect
-       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4646-4"
-       width="13"
-       height="12.999998"
-       x="505"
-       y="901.36218" />
-    <rect
-       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4646-4-6"
-       width="13"
-       height="12.999996"
-       x="505"
-       y="917.36218"
-       inkscape:export-filename="/home/rahah/elvidishu/steak/unreal/dev/skins/external link icons/mail.png"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <rect
-       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4646-4-6-9"
-       width="13"
-       height="12.999996"
-       x="505"
-       y="933.36218" />
-    <rect
-       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4646-4-6-6"
-       width="13"
-       height="12.999996"
-       x="505"
-       y="950.36218" />
-    <rect
-       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4646-4-6-2"
-       width="13"
-       height="12.999998"
-       x="505"
-       y="966.36218" />
-    <rect
-       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
-       id="rect4646-44"
-       width="13"
-       height="12.999996"
-       x="505"
-       y="869.36218" />
-  </g>
-  <g
-     inkscape:label="sketch 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-505,-869.36218)"
-     style="display:none"
-     sodipodi:insensitive="true">
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 507,870.36218 0,5 3,0 4,4 0,-13 -4,4 z"
-       id="path3194"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 517,869.36218 c 1,2 1,5 0,7"
-       id="path3196"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 520,867.36218 c 2,2 2,9 0,11"
-       id="path3198"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 507.93861,989.90562 0,15.99988 13,0 0,-10.99988 -5,-5 z"
-       id="path3200"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 506.93861,918.90546 0,11.5 15,0 0,-11.5 z"
-       id="path3202"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 506.93861,918.90546 7.5,6 7.5,-6"
-       id="path3204"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 507.93861,890.90546 3,0"
-       id="path3212"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 507.93861,893.90546 3,0"
-       id="path3214"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 507.93861,899.90546 3,0"
-       id="path3218"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 507.93861,902.90546 3,0"
-       id="path3220"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 517.93861,890.90546 3,0"
-       id="path3222"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 507.93861,896.90546 13,0"
-       id="path3224"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 517.93861,893.90546 3,0"
-       id="path3226"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 517.93861,899.90546 3,0"
-       id="path3230"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 517.93861,902.90546 3,0"
-       id="path3232"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 510.93861,890.90546 0,12 7,0 0,-12 z"
-       id="path3206"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 507.93861,888.90546 0,16"
-       id="path3208"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 520.93861,888.90546 0,16"
-       id="path3210"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 515.93861,989.90562 0,5 5,0"
-       id="path3234"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 513.93861,969.40546 c -2,0 -5,0 -7,0 l 0,10.99995 11,5e-5 c 0,-2.33332 0,-4.66668 0,-7"
-       id="path3236"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none"
-       d="m 513.93861,976.40546 5,-4 3,3 0,-10 -10,0 3,3 -4,5"
-       id="path3242"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <path
-       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 506.93861,940.40546 15,0 0,10 -6,0 -6,4 1,-4 -4,0 z"
-       id="path3244"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccc" />
-    <path
-       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m 509.93861,972.40546 c 2,1 4,3 5,5"
-       id="path4641"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer4"
-     inkscape:label="sketch 2"
-     style="display:none"
-     transform="translate(0,-6.0000106)">
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 8.4921988,1.0623917 -4.0641234,4.064123 -3.2512987,0 0,5.6897733 3.2512987,0 4.0641234,4.064124 z m -1.6256494,4.064124 0,5.6897733 -1.6256493,-1.6256493 -2.438474,-1e-6 0,-2.438474 2.438474,1e-6 z"
-       id="path4755-9"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 9.3050235,5.1265157 c 0,-0.812824 0.8128245,-1.625649 1.6256495,-0.812824 0,0 0.812825,0.812824 0.812825,3.251298 0,2.4384743 -0.812825,3.2512993 -0.812825,3.2512993 -0.812825,0.812825 -1.6256495,0 -1.6256495,-0.812825 0,0 0.8128245,-0.8128243 0.8128245,-2.4384743 0,-1.625649 -0.8128245,-2.438474 -0.8128245,-2.438474 z"
-       id="path4760-1"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccsccsc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 11.743498,3.5008667 c 0,-0.812825 0.812824,-1.625649 1.625649,-0.812825 0,0 1.625649,1.62565 1.625649,4.876948 0,3.2512993 -1.625649,4.8769483 -1.625649,4.8769483 -0.812825,0.812825 -1.625649,0 -1.625649,-0.812824 0,0 1.625649,-1.62565 1.625649,-4.0641243 0,-2.438474 -1.625649,-4.064123 -1.625649,-4.064123 z"
-       id="path4762-8"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccsccsc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 2.8024261,23.008658 0,0.812825 10.5667209,0 0,-0.812825 z"
-       id="path4772"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 2.8024261,33.575379 10.5667209,0 0,-0.812825 -10.5667209,0 z"
-       id="path4774"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 2.8024261,25.447132 0,0.812824 2.438474,0 0,-0.812824 z m 8.1282469,0 0,0.812824 2.438474,0 0,-0.812824 z"
-       id="path4782"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 2.8024261,30.32408 0,0.812824 2.438474,0 0,-0.812824 z m 8.1282469,0 0,0.812824 2.438474,0 0,-0.812824 z"
-       id="path4778"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 2.8024261,28.698431 10.5667209,0 0,-0.812825 -10.5667209,0 z"
-       id="path4780"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 5.2409001,27.479194 0,1.625649 5.6897729,0 0,-1.625649 z"
-       id="path4793"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 4.4280754,23.008658 0,10.56672 7.3154226,0 0,-10.56672 z m 1.6256494,1.625649 4.0641232,0 0,7.315422 -4.0641232,0 z"
-       id="path4768"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 1.9896014,21.383009 1.6256493,0 0,13.818019 -1.6256493,0 z"
-       id="path4764"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 12.556322,21.383009 1.62565,0 0,13.818019 -1.62565,0 z"
-       id="path4766"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 1.9896014,44.954923 6.096185,5.689773 6.0961856,-5.689773 -0.812825,-0.812825 -1.625649,0.813196 -3.6577116,3.251298 -3.657711,-3.251298 -1.6256493,-0.813196 z"
-       id="path4800-4"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 1.1767767,43.329273 0,11.379545 13.8180193,0 0,-11.379545 z m 1.6256494,1.625649 10.5667209,0 0,8.128247 -10.5667209,0 z"
-       id="path4795-8"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 1.9896014,62.024243 -0.8128247,0.812824 0,8.128247 0.8128247,0.812825 2.438474,0 -0.8128247,3.251297 5.6897728,-3.251297 4.8769485,0 0.812824,-0.812825 0,-8.128247 -0.812824,-0.812824 z m 0.8128247,1.625649 10.5667209,0 0,6.502598 -4.0641235,0 -3.5815088,2.133664 0.9144278,-2.133664 -3.8355164,0 z"
-       id="path4802-8"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 4.4280754,82.344856 10.5667206,0 0,10.56672 -3.251298,-3.25129 -3.2512992,2.43847 -0.8128247,-0.81282 4.0641239,-3.2513 1.625649,1.62565 0,-5.68978 -5.6897729,0 1.6256494,1.62565 -3.2512987,4.06413 -0.8128247,-0.81283 2.438474,-3.2513 z"
-       id="path4807-5"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 8.4921988,85.596156 -7.3154221,0 0,10.56672 10.5667213,0 0,-7.31542 -1.62565,0.81283 0,4.87694 -7.3154219,0 0,-7.31542 4.876948,0 z"
-       id="path4809-7"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 8.4921988,103.47831 0,4.87694 4.8769482,0 0,-1.62565 -3.251299,0 0,-3.25129 z"
-       id="path4818-67"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 1.9896014,102.66548 0,13.81802 12.1923706,0 0,-10.13799 -3.657711,-3.68003 z m 1.6256493,1.62565 6.5025973,0 2.438474,2.43847 0,8.12825 -8.9410713,0 z"
-       id="path4813-2"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 3.6152507,88.847456 c 0,-0.81282 0.8128247,-0.81282 0.8128247,-0.81282 2.438474,0.81282 4.0641234,2.43847 4.8769481,4.87694 0,0 0,0.81283 -0.8128247,0.81283 -1.6256494,-2.43847 -2.438474,-3.2513 -4.8769481,-4.87695 z"
-       id="path4822-8"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer3"
-     inkscape:label="Layer"
-     style="display:none"
-     transform="translate(-10,-26.000007)">
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none"
-       d="m 19,20.999995 -4,4 -3,0 0,6 3,0 4,4 z m -1,2.5 0,9 -2.6,-2.5 -2.4,0 0,-4 2.5,0 z"
-       id="path4755"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none"
-       d="m 19.75,24.999995 c 0,-1 0.75,-1 0.75,-1 0,0 1.5,1.029412 1.5,3.5 0,2.470588 -1.5,3.5 -1.5,3.5 0,0 -0.75,0 -0.75,-1 0,0 1,-0.852941 1,-2.5 0,-1.647059 -1,-2.5 -1,-2.5 z"
-       id="path4760"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccsccsc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none"
-       d="m 22.25,23.999995 c 0,-1 0.75,-1 0.75,-1 0,0 2,1.205882 2,4.5 0,3.294118 -2,4.5 -2,4.5 0,0 -0.75,0 -0.75,-1 0,0 1.5,-1.029412 1.5,-3.5 0,-2.470588 -1.5,-3.5 -1.5,-3.5 z"
-       id="path4762"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccsccsc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none"
-       d="m 31.4375,79.875 -1,1 0,10 1,1 3,0 -1,4 7,-4 6,0 1,-1 0,-10 -1,-1 z m 1,2 13,0 0,8 -5,0 -4.40625,2.625 1.125,-2.625 -4.71875,0 z"
-       id="path4802"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none"
-       d="m 35.125,98.8125 13,0 0,13 -4,-4 -4,3 -1,-1 5,-4 2,2 0,-7 -7,0 2,2 -4,5 -1,-1 3,-4 z"
-       id="path4807"
-       inkscape:connector-curvature="0" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none"
-       d="m 40.125,102.8125 -9,0 0,13 13,0 0,-9 -2,1 0,6 -9,0 0,-9 6,0 z"
-       id="path4809"
-       inkscape:connector-curvature="0" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none"
-       d="m 34.125,106.8125 c 0,-1 1,-1 1,-1 3,1 5,3 6,6 0,0 0,1 -1,1 -2,-3 -3,-4 -6,-6 z"
-       id="path4822"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       d="m 12,50.499995 0,1 3,0 0,-1 -3,0 z m 9,0 0,1 3,0 0,-1 -3,0 z"
-       id="rect4841"
-       inkscape:connector-curvature="0" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       d="m 12,44.499995 0,1 3,0 0,-1 -3,0 z m 9,0 0,1 3,0 0,-1 -3,0 z"
-       id="rect4843"
-       inkscape:connector-curvature="0" />
-    <path
-       inkscape:connector-curvature="0"
-       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
-       d="m 12,52.999995 0,1 3,0 0,-1 z m 9,0 0,1 3,0 0,-1 z"
-       id="rect4843-1"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       inkscape:connector-curvature="0"
-       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
-       d="m 12,41.999995 0,1 3,0 0,-1 z m 9,0 0,1 3,0 0,-1 z"
-       id="rect4843-17"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
-       d="m 12,47.499995 0,1 3,0 0,-1 z m 9,0 0,1 3,0 0,-1 z"
-       id="rect4841-9"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <rect
-       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4835"
-       width="7"
-       height="2"
-       x="4"
-       y="27"
-       transform="translate(10,19.999995)" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none"
-       d="m 2,21 1,0 0,14 -1,0 z"
-       id="path4826"
-       inkscape:connector-curvature="0"
-       transform="translate(10,19.999995)"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none"
-       d="m 13,21 1,0 0,14 -1,0 z"
-       id="path4828"
-       inkscape:connector-curvature="0"
-       transform="translate(10,19.999995)"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none"
-       d="m 4,22 0,12 8,0 0,-12 z m 1,1 6,0 0,10 -6,0 z"
-       transform="translate(10,19.999995)"
-       id="path4830"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <rect
-       style="fill:#3366bb;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4837"
-       width="8"
-       height="1"
-       x="4"
-       y="22"
-       transform="translate(10,19.999995)" />
-    <rect
-       style="fill:#3366bb;fill-opacity:1;fill-rule:evenodd;stroke:none"
-       id="rect4839"
-       width="8"
-       height="1"
-       x="4"
-       y="33"
-       transform="translate(10,19.999995)" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none"
-       d="m 12,64.999995 6,5 6,-5 0.53033,-1.45299 -1.28033,0.45299 -5.25,4.5 -5.25,-4.5 -1.236136,-0.53033 z"
-       id="path4910"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none"
-       d="m 11,62.999995 0,10 14,0 0,-10 z m 1,1 12,0 0,8 -12,0 z"
-       id="path4905"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 19,121 0,5 5,0 -1,-1 -3,0 0,-3 z"
-       id="path4818-6"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 12,121 0,14 12,0 0,-10 -4,-4 z m 1,1 6.5,0 3.5,3.5 0,8.5 -10,0 z"
-       id="path4813-3"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccc" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer5"
-     inkscape:label="Layer#1"
-     style="opacity:0.98999999"
-     transform="translate(0,-6.0000106)">
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 7,23.000004 -3,3 -3,0 0,4 3,0 3,3 z m -1,2.500001 0,5 -1.5,-1.500001 -2.5,0 0,-2 2.5,0 z"
-       id="path4755-9-5"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 7.4319858,26.075368 c 0,-0.621323 0.6213237,-1.242647 1.2426477,-0.621323 0,0 0.6213228,0.621323 0.6213228,2.485294 0,1.863971 -0.6213228,2.485294 -0.6213228,2.485294 -0.621324,0.621324 -1.2426477,0 -1.2426477,-0.621323 0,0 0.6213237,-0.621324 0.6213237,-1.863971 0,-1.242648 -0.6213237,-1.863971 -0.6213237,-1.863971 z"
-       id="path4760-1-7"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccsccsc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 9.2959563,24.832721 c 0,-0.621324 0.6213228,-1.242647 1.2426477,-0.621324 0,0 1.242646,1.242648 1.242646,3.727942 0,2.485294 -1.242646,3.727941 -1.242646,3.727941 -0.6213249,0.621324 -1.2426477,0 -1.2426477,-0.621323 0,0 1.2426477,-1.242647 1.2426477,-3.106618 0,-1.863971 -1.2426477,-3.106618 -1.2426477,-3.106618 z"
-       id="path4762-8-3"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccsccsc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
-       d="m 2.4916056,40.000004 0,0.621323 8.0979164,0 0,-0.621323 z"
-       id="path4772-4"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
-       d="m 2.4916056,48.000004 8.0979164,0 0,-0.621324 -8.0979164,0 z"
-       id="path4774-6"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
-       d="m 2.4916056,41.919118 0,0.621323 1.8687499,0 0,-0.621323 z m 6.2291665,0 0,0.621323 1.8687499,0 0,-0.621323 z"
-       id="path4782-3"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
-       d="m 2.4916056,45.589344 0,0.621322 1.8687499,0 0,-0.621322 z m 6.2291665,0 0,0.621322 1.8687499,0 0,-0.621322 z"
-       id="path4778-9"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
-       d="m 2.4916056,44.404412 8.0979164,0 0,-0.621323 -8.0979164,0 z"
-       id="path4780-0"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 4.3603555,43.472427 0,1.242647 4.3604166,0 0,-1.242647 z"
-       id="path4793-0"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 4,40.000004 0,8 5,0 0,-8 z m 1,1 3,0 0,6 -3,0 z"
-       id="path4768-5"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 2,39.000004 1,0 0,10 -1,0 z"
-       id="path4764-1"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 10,39.000004 1,0 0,10 -1,0 z"
-       id="path4766-6"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="M 1.8400738,58.055766 6.5000005,62.405031 11.159927,58.055766 10.538604,57.434442 9.2959563,58.056049 6.5000005,60.541343 3.7040445,58.056049 2.4613977,57.434442 z"
-       id="path4800-4-9"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccccc"
-       inkscape:export-filename="/home/rahah/elvidishu/steak/unreal/dev/skins/external link icons/mail.png"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 1,57.000008 0,8 11,0 0,-8 z m 1,1 9,0 0,6 -9,0 z"
-       id="path4795-8-2"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccc"
-       inkscape:export-filename="/home/rahah/elvidishu/steak/unreal/dev/skins/external link icons/mail.png"
-       inkscape:export-xdpi="90"
-       inkscape:export-ydpi="90" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="M 1.6213238,72.000004 1,72.621328 l 0,5.757352 0.6213238,0.621324 1.6894529,0 L 2.6894528,81.727943 7,79.000004 l 4.378677,0 L 12,78.37868 12,72.621328 11.378677,72.000004 z m 0.3786762,1 9,0 0,5 -4,0 L 4.0978858,79.896603 5,78.000004 l -3,0 z"
-       id="path4802-8-9"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 5,88.000004 7,0 0,7 -2,-2 -3,2 0,-1 3,-2.249999 1,1 0,-3.750001 -3.75,0 1,1 -2.25,3 -1,0 2,-3 z"
-       id="path4807-5-6"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccccccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 7,90.000004 -5,0 0,8 8,0 0,-5 -1,0 0,4 -6,0 0,-6 4,0 z"
-       id="path4809-7-3"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 7.5,105.00001 0,3 2.5,0 1,-1 -2.5,0 0,-3 z"
-       id="path4818-67-7"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccc" />
-    <path
-       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
-       d="m 3,104 0,10 8,1e-5 0,-7 -2.5,-3 z m 1,1 4,1e-5 2,2.50001 0,5.49999 -6,0 z"
-       id="path4813-2-2"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccc" />
-    <path
-       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
-       d="m 4.0827206,92.533089 c 0,-0.621319 0.6213239,-0.621319 0.6213239,-0.621319 1.8639706,0.621319 3.1066175,1.863968 3.7279413,3.727935 0,0 0,0.621328 -0.6213238,0.621328 C 6.5680151,94.397065 5.9466913,93.775738 4.0827206,92.533089 z"
-       id="path4822-8-2"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3465ba;fill-opacity:1;stroke:none;display:inline"
-       d="m 1,8.500006 0,7.5001 1,-0.9872 0,-6.0129 2,0 2,1 4,-2e-4 0,2.0002 1,0 0,-2.5 -0.5,-0.5002 -4.5,2e-4 -2,-1 -2.5,0 z"
-       id="path3209"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccccccccccccc" />
-    <path
-       style="fill:#16a4e8;fill-opacity:1;stroke:none;display:inline"
-       d="m 6,11.000106 -1,-10e-5 -2.5,0 -0.5,0.5 -1,4.5001 10,-10e-5 0,-4.4998 -0.5,-0.5 z m 0,1 4,-10e-5 0,3 -7.75,-1e-4 0.75,-3.0001 2,0 z"
-       id="path3215"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cccccccccccccccc" />
-    <path
-       style="fill:#3465ba;fill-opacity:1;stroke:none;display:inline"
-       d="m 2,17.000006 0,1 8,0 0,-1 z"
-       id="path3247"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       style="fill:#3465ba;fill-opacity:1;stroke:none;display:inline"
-       d="m 5,15.500006 0,2 2,0 0,-2 c 0,-0.5 -2,-0.5 -2,0 z"
-       id="path3249"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccccc" />
-  </g>
-</svg>
diff --git a/resources/src/mediawiki.skinning/images/external-link-icons.svg b/resources/src/mediawiki.skinning/images/external-link-icons.svg
new file mode 100644 (file)
index 0000000..6a67993
--- /dev/null
@@ -0,0 +1,697 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="13"
+   height="110"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.5 r10040"
+   sodipodi:docname="external link icons.svg">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="15.999999"
+     inkscape:cx="10.40536"
+     inkscape:cy="65.686256"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer5"
+     showgrid="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1283"
+     inkscape:window-height="711"
+     inkscape:window-x="1790"
+     inkscape:window-y="-6"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3246"
+       empspacing="4"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       originx="0px"
+       originy="-27.999997px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="base"
+     style="display:none"
+     transform="translate(-505,-869.36218)">
+    <rect
+       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4646"
+       width="13"
+       height="12.999996"
+       x="505"
+       y="885.36218" />
+    <rect
+       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4646-4"
+       width="13"
+       height="12.999998"
+       x="505"
+       y="901.36218" />
+    <rect
+       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4646-4-6"
+       width="13"
+       height="12.999996"
+       x="505"
+       y="917.36218"
+       inkscape:export-filename="/home/rahah/elvidishu/steak/unreal/dev/skins/external link icons/mail.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <rect
+       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4646-4-6-9"
+       width="13"
+       height="12.999996"
+       x="505"
+       y="933.36218" />
+    <rect
+       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4646-4-6-6"
+       width="13"
+       height="12.999996"
+       x="505"
+       y="950.36218" />
+    <rect
+       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4646-4-6-2"
+       width="13"
+       height="12.999998"
+       x="505"
+       y="966.36218" />
+    <rect
+       style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+       id="rect4646-44"
+       width="13"
+       height="12.999996"
+       x="505"
+       y="869.36218" />
+  </g>
+  <g
+     inkscape:label="sketch 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-505,-869.36218)"
+     style="display:none"
+     sodipodi:insensitive="true">
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 507,870.36218 0,5 3,0 4,4 0,-13 -4,4 z"
+       id="path3194"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 517,869.36218 c 1,2 1,5 0,7"
+       id="path3196"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 520,867.36218 c 2,2 2,9 0,11"
+       id="path3198"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 507.93861,989.90562 0,15.99988 13,0 0,-10.99988 -5,-5 z"
+       id="path3200"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 506.93861,918.90546 0,11.5 15,0 0,-11.5 z"
+       id="path3202"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 506.93861,918.90546 7.5,6 7.5,-6"
+       id="path3204"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 507.93861,890.90546 3,0"
+       id="path3212"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 507.93861,893.90546 3,0"
+       id="path3214"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 507.93861,899.90546 3,0"
+       id="path3218"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 507.93861,902.90546 3,0"
+       id="path3220"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 517.93861,890.90546 3,0"
+       id="path3222"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 507.93861,896.90546 13,0"
+       id="path3224"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 517.93861,893.90546 3,0"
+       id="path3226"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 517.93861,899.90546 3,0"
+       id="path3230"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 517.93861,902.90546 3,0"
+       id="path3232"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 510.93861,890.90546 0,12 7,0 0,-12 z"
+       id="path3206"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 507.93861,888.90546 0,16"
+       id="path3208"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 520.93861,888.90546 0,16"
+       id="path3210"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 515.93861,989.90562 0,5 5,0"
+       id="path3234"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 513.93861,969.40546 c -2,0 -5,0 -7,0 l 0,10.99995 11,5e-5 c 0,-2.33332 0,-4.66668 0,-7"
+       id="path3236"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none"
+       d="m 513.93861,976.40546 5,-4 3,3 0,-10 -10,0 3,3 -4,5"
+       id="path3242"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="fill:none;stroke:#0066ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 506.93861,940.40546 15,0 0,10 -6,0 -6,4 1,-4 -4,0 z"
+       id="path3244"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       style="fill:none;stroke:#5b9dff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 509.93861,972.40546 c 2,1 4,3 5,5"
+       id="path4641"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer4"
+     inkscape:label="sketch 2"
+     style="display:none"
+     transform="translate(0,-6.0000106)">
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 8.4921988,1.0623917 -4.0641234,4.064123 -3.2512987,0 0,5.6897733 3.2512987,0 4.0641234,4.064124 z m -1.6256494,4.064124 0,5.6897733 -1.6256493,-1.6256493 -2.438474,-1e-6 0,-2.438474 2.438474,1e-6 z"
+       id="path4755-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 9.3050235,5.1265157 c 0,-0.812824 0.8128245,-1.625649 1.6256495,-0.812824 0,0 0.812825,0.812824 0.812825,3.251298 0,2.4384743 -0.812825,3.2512993 -0.812825,3.2512993 -0.812825,0.812825 -1.6256495,0 -1.6256495,-0.812825 0,0 0.8128245,-0.8128243 0.8128245,-2.4384743 0,-1.625649 -0.8128245,-2.438474 -0.8128245,-2.438474 z"
+       id="path4760-1"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccsccsc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 11.743498,3.5008667 c 0,-0.812825 0.812824,-1.625649 1.625649,-0.812825 0,0 1.625649,1.62565 1.625649,4.876948 0,3.2512993 -1.625649,4.8769483 -1.625649,4.8769483 -0.812825,0.812825 -1.625649,0 -1.625649,-0.812824 0,0 1.625649,-1.62565 1.625649,-4.0641243 0,-2.438474 -1.625649,-4.064123 -1.625649,-4.064123 z"
+       id="path4762-8"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccsccsc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 2.8024261,23.008658 0,0.812825 10.5667209,0 0,-0.812825 z"
+       id="path4772"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 2.8024261,33.575379 10.5667209,0 0,-0.812825 -10.5667209,0 z"
+       id="path4774"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 2.8024261,25.447132 0,0.812824 2.438474,0 0,-0.812824 z m 8.1282469,0 0,0.812824 2.438474,0 0,-0.812824 z"
+       id="path4782"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 2.8024261,30.32408 0,0.812824 2.438474,0 0,-0.812824 z m 8.1282469,0 0,0.812824 2.438474,0 0,-0.812824 z"
+       id="path4778"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 2.8024261,28.698431 10.5667209,0 0,-0.812825 -10.5667209,0 z"
+       id="path4780"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 5.2409001,27.479194 0,1.625649 5.6897729,0 0,-1.625649 z"
+       id="path4793"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 4.4280754,23.008658 0,10.56672 7.3154226,0 0,-10.56672 z m 1.6256494,1.625649 4.0641232,0 0,7.315422 -4.0641232,0 z"
+       id="path4768"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 1.9896014,21.383009 1.6256493,0 0,13.818019 -1.6256493,0 z"
+       id="path4764"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 12.556322,21.383009 1.62565,0 0,13.818019 -1.62565,0 z"
+       id="path4766"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 1.9896014,44.954923 6.096185,5.689773 6.0961856,-5.689773 -0.812825,-0.812825 -1.625649,0.813196 -3.6577116,3.251298 -3.657711,-3.251298 -1.6256493,-0.813196 z"
+       id="path4800-4"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 1.1767767,43.329273 0,11.379545 13.8180193,0 0,-11.379545 z m 1.6256494,1.625649 10.5667209,0 0,8.128247 -10.5667209,0 z"
+       id="path4795-8"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 1.9896014,62.024243 -0.8128247,0.812824 0,8.128247 0.8128247,0.812825 2.438474,0 -0.8128247,3.251297 5.6897728,-3.251297 4.8769485,0 0.812824,-0.812825 0,-8.128247 -0.812824,-0.812824 z m 0.8128247,1.625649 10.5667209,0 0,6.502598 -4.0641235,0 -3.5815088,2.133664 0.9144278,-2.133664 -3.8355164,0 z"
+       id="path4802-8"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 4.4280754,82.344856 10.5667206,0 0,10.56672 -3.251298,-3.25129 -3.2512992,2.43847 -0.8128247,-0.81282 4.0641239,-3.2513 1.625649,1.62565 0,-5.68978 -5.6897729,0 1.6256494,1.62565 -3.2512987,4.06413 -0.8128247,-0.81283 2.438474,-3.2513 z"
+       id="path4807-5"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 8.4921988,85.596156 -7.3154221,0 0,10.56672 10.5667213,0 0,-7.31542 -1.62565,0.81283 0,4.87694 -7.3154219,0 0,-7.31542 4.876948,0 z"
+       id="path4809-7"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 8.4921988,103.47831 0,4.87694 4.8769482,0 0,-1.62565 -3.251299,0 0,-3.25129 z"
+       id="path4818-67"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 1.9896014,102.66548 0,13.81802 12.1923706,0 0,-10.13799 -3.657711,-3.68003 z m 1.6256493,1.62565 6.5025973,0 2.438474,2.43847 0,8.12825 -8.9410713,0 z"
+       id="path4813-2"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 3.6152507,88.847456 c 0,-0.81282 0.8128247,-0.81282 0.8128247,-0.81282 2.438474,0.81282 4.0641234,2.43847 4.8769481,4.87694 0,0 0,0.81283 -0.8128247,0.81283 -1.6256494,-2.43847 -2.438474,-3.2513 -4.8769481,-4.87695 z"
+       id="path4822-8"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer3"
+     inkscape:label="Layer"
+     style="display:none"
+     transform="translate(-10,-26.000007)">
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none"
+       d="m 19,20.999995 -4,4 -3,0 0,6 3,0 4,4 z m -1,2.5 0,9 -2.6,-2.5 -2.4,0 0,-4 2.5,0 z"
+       id="path4755"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none"
+       d="m 19.75,24.999995 c 0,-1 0.75,-1 0.75,-1 0,0 1.5,1.029412 1.5,3.5 0,2.470588 -1.5,3.5 -1.5,3.5 0,0 -0.75,0 -0.75,-1 0,0 1,-0.852941 1,-2.5 0,-1.647059 -1,-2.5 -1,-2.5 z"
+       id="path4760"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccsccsc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none"
+       d="m 22.25,23.999995 c 0,-1 0.75,-1 0.75,-1 0,0 2,1.205882 2,4.5 0,3.294118 -2,4.5 -2,4.5 0,0 -0.75,0 -0.75,-1 0,0 1.5,-1.029412 1.5,-3.5 0,-2.470588 -1.5,-3.5 -1.5,-3.5 z"
+       id="path4762"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccsccsc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none"
+       d="m 31.4375,79.875 -1,1 0,10 1,1 3,0 -1,4 7,-4 6,0 1,-1 0,-10 -1,-1 z m 1,2 13,0 0,8 -5,0 -4.40625,2.625 1.125,-2.625 -4.71875,0 z"
+       id="path4802"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none"
+       d="m 35.125,98.8125 13,0 0,13 -4,-4 -4,3 -1,-1 5,-4 2,2 0,-7 -7,0 2,2 -4,5 -1,-1 3,-4 z"
+       id="path4807"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none"
+       d="m 40.125,102.8125 -9,0 0,13 13,0 0,-9 -2,1 0,6 -9,0 0,-9 6,0 z"
+       id="path4809"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none"
+       d="m 34.125,106.8125 c 0,-1 1,-1 1,-1 3,1 5,3 6,6 0,0 0,1 -1,1 -2,-3 -3,-4 -6,-6 z"
+       id="path4822"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       d="m 12,50.499995 0,1 3,0 0,-1 -3,0 z m 9,0 0,1 3,0 0,-1 -3,0 z"
+       id="rect4841"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       d="m 12,44.499995 0,1 3,0 0,-1 -3,0 z m 9,0 0,1 3,0 0,-1 -3,0 z"
+       id="rect4843"
+       inkscape:connector-curvature="0" />
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+       d="m 12,52.999995 0,1 3,0 0,-1 z m 9,0 0,1 3,0 0,-1 z"
+       id="rect4843-1"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+       d="m 12,41.999995 0,1 3,0 0,-1 z m 9,0 0,1 3,0 0,-1 z"
+       id="rect4843-17"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+       d="m 12,47.499995 0,1 3,0 0,-1 z m 9,0 0,1 3,0 0,-1 z"
+       id="rect4841-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <rect
+       style="fill:#15a5ea;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4835"
+       width="7"
+       height="2"
+       x="4"
+       y="27"
+       transform="translate(10,19.999995)" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none"
+       d="m 2,21 1,0 0,14 -1,0 z"
+       id="path4826"
+       inkscape:connector-curvature="0"
+       transform="translate(10,19.999995)"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none"
+       d="m 13,21 1,0 0,14 -1,0 z"
+       id="path4828"
+       inkscape:connector-curvature="0"
+       transform="translate(10,19.999995)"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none"
+       d="m 4,22 0,12 8,0 0,-12 z m 1,1 6,0 0,10 -6,0 z"
+       transform="translate(10,19.999995)"
+       id="path4830"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <rect
+       style="fill:#3366bb;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4837"
+       width="8"
+       height="1"
+       x="4"
+       y="22"
+       transform="translate(10,19.999995)" />
+    <rect
+       style="fill:#3366bb;fill-opacity:1;fill-rule:evenodd;stroke:none"
+       id="rect4839"
+       width="8"
+       height="1"
+       x="4"
+       y="33"
+       transform="translate(10,19.999995)" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none"
+       d="m 12,64.999995 6,5 6,-5 0.53033,-1.45299 -1.28033,0.45299 -5.25,4.5 -5.25,-4.5 -1.236136,-0.53033 z"
+       id="path4910"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none"
+       d="m 11,62.999995 0,10 14,0 0,-10 z m 1,1 12,0 0,8 -12,0 z"
+       id="path4905"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 19,121 0,5 5,0 -1,-1 -3,0 0,-3 z"
+       id="path4818-6"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 12,121 0,14 12,0 0,-10 -4,-4 z m 1,1 6.5,0 3.5,3.5 0,8.5 -10,0 z"
+       id="path4813-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccc" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer5"
+     inkscape:label="Layer#1"
+     style="opacity:0.98999999"
+     transform="translate(0,-6.0000106)">
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 7,23.000004 -3,3 -3,0 0,4 3,0 3,3 z m -1,2.500001 0,5 -1.5,-1.500001 -2.5,0 0,-2 2.5,0 z"
+       id="path4755-9-5"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 7.4319858,26.075368 c 0,-0.621323 0.6213237,-1.242647 1.2426477,-0.621323 0,0 0.6213228,0.621323 0.6213228,2.485294 0,1.863971 -0.6213228,2.485294 -0.6213228,2.485294 -0.621324,0.621324 -1.2426477,0 -1.2426477,-0.621323 0,0 0.6213237,-0.621324 0.6213237,-1.863971 0,-1.242648 -0.6213237,-1.863971 -0.6213237,-1.863971 z"
+       id="path4760-1-7"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccsccsc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 9.2959563,24.832721 c 0,-0.621324 0.6213228,-1.242647 1.2426477,-0.621324 0,0 1.242646,1.242648 1.242646,3.727942 0,2.485294 -1.242646,3.727941 -1.242646,3.727941 -0.6213249,0.621324 -1.2426477,0 -1.2426477,-0.621323 0,0 1.2426477,-1.242647 1.2426477,-3.106618 0,-1.863971 -1.2426477,-3.106618 -1.2426477,-3.106618 z"
+       id="path4762-8-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccsccsc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
+       d="m 2.4916056,40.000004 0,0.621323 8.0979164,0 0,-0.621323 z"
+       id="path4772-4"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
+       d="m 2.4916056,48.000004 8.0979164,0 0,-0.621324 -8.0979164,0 z"
+       id="path4774-6"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
+       d="m 2.4916056,41.919118 0,0.621323 1.8687499,0 0,-0.621323 z m 6.2291665,0 0,0.621323 1.8687499,0 0,-0.621323 z"
+       id="path4782-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
+       d="m 2.4916056,45.589344 0,0.621322 1.8687499,0 0,-0.621322 z m 6.2291665,0 0,0.621322 1.8687499,0 0,-0.621322 z"
+       id="path4778-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:0.99215686;stroke:none;display:inline"
+       d="m 2.4916056,44.404412 8.0979164,0 0,-0.621323 -8.0979164,0 z"
+       id="path4780-0"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 4.3603555,43.472427 0,1.242647 4.3604166,0 0,-1.242647 z"
+       id="path4793-0"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 4,40.000004 0,8 5,0 0,-8 z m 1,1 3,0 0,6 -3,0 z"
+       id="path4768-5"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 2,39.000004 1,0 0,10 -1,0 z"
+       id="path4764-1"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 10,39.000004 1,0 0,10 -1,0 z"
+       id="path4766-6"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="M 1.8400738,58.055766 6.5000005,62.405031 11.159927,58.055766 10.538604,57.434442 9.2959563,58.056049 6.5000005,60.541343 3.7040445,58.056049 2.4613977,57.434442 z"
+       id="path4800-4-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccc"
+       inkscape:export-filename="/home/rahah/elvidishu/steak/unreal/dev/skins/external link icons/mail.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 1,57.000008 0,8 11,0 0,-8 z m 1,1 9,0 0,6 -9,0 z"
+       id="path4795-8-2"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccc"
+       inkscape:export-filename="/home/rahah/elvidishu/steak/unreal/dev/skins/external link icons/mail.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="M 1.6213238,72.000004 1,72.621328 l 0,5.757352 0.6213238,0.621324 1.6894529,0 L 2.6894528,81.727943 7,79.000004 l 4.378677,0 L 12,78.37868 12,72.621328 11.378677,72.000004 z m 0.3786762,1 9,0 0,5 -4,0 L 4.0978858,79.896603 5,78.000004 l -3,0 z"
+       id="path4802-8-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 5,88.000004 7,0 0,7 -2,-2 -3,2 0,-1 3,-2.249999 1,1 0,-3.750001 -3.75,0 1,1 -2.25,3 -1,0 2,-3 z"
+       id="path4807-5-6"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 7,90.000004 -5,0 0,8 8,0 0,-5 -1,0 0,4 -6,0 0,-6 4,0 z"
+       id="path4809-7-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 7.5,105.00001 0,3 2.5,0 1,-1 -2.5,0 0,-3 z"
+       id="path4818-67-7"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="fill:#3366bb;fill-opacity:1;stroke:none;display:inline"
+       d="m 3,104 0,10 8,1e-5 0,-7 -2.5,-3 z m 1,1 4,1e-5 2,2.50001 0,5.49999 -6,0 z"
+       id="path4813-2-2"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccc" />
+    <path
+       style="fill:#15a5ea;fill-opacity:1;stroke:none;display:inline"
+       d="m 4.0827206,92.533089 c 0,-0.621319 0.6213239,-0.621319 0.6213239,-0.621319 1.8639706,0.621319 3.1066175,1.863968 3.7279413,3.727935 0,0 0,0.621328 -0.6213238,0.621328 C 6.5680151,94.397065 5.9466913,93.775738 4.0827206,92.533089 z"
+       id="path4822-8-2"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3465ba;fill-opacity:1;stroke:none;display:inline"
+       d="m 1,8.500006 0,7.5001 1,-0.9872 0,-6.0129 2,0 2,1 4,-2e-4 0,2.0002 1,0 0,-2.5 -0.5,-0.5002 -4.5,2e-4 -2,-1 -2.5,0 z"
+       id="path3209"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccccccccc" />
+    <path
+       style="fill:#16a4e8;fill-opacity:1;stroke:none;display:inline"
+       d="m 6,11.000106 -1,-10e-5 -2.5,0 -0.5,0.5 -1,4.5001 10,-10e-5 0,-4.4998 -0.5,-0.5 z m 0,1 4,-10e-5 0,3 -7.75,-1e-4 0.75,-3.0001 2,0 z"
+       id="path3215"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccccccc" />
+    <path
+       style="fill:#3465ba;fill-opacity:1;stroke:none;display:inline"
+       d="m 2,17.000006 0,1 8,0 0,-1 z"
+       id="path3247"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#3465ba;fill-opacity:1;stroke:none;display:inline"
+       d="m 5,15.500006 0,2 2,0 0,-2 c 0,-0.5 -2,-0.5 -2,0 z"
+       id="path3249"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc" />
+  </g>
+</svg>
index b27d2a5..a06aa95 100644 (file)
        unicode-bidi: -moz-isolate;
        unicode-bidi: isolate;
 }
-
-/* Comment portions of RC entries */
-span.comment {
-       font-style: italic;
-       unicode-bidi: -moz-isolate;
-       unicode-bidi: isolate;
-}
index ceb93c2..d65b284 100644 (file)
@@ -40,8 +40,3 @@
 #mw-editbutton-hr {
        .background-image("images/@{button-hr}");
 }
-
-// Awful workaround for T113868, while it awaits a better fix.
-#mw-t113868 {
-       background-image: url( images/ar/button_bold.png ), url( images/ar/button_headline.png ), url( images/ar/button_italic.png ), url( images/ar/button_link.png ), url( images/ar/button_nowiki.png ), url( images/be-tarask/button_bold.png ), url( images/be-tarask/button_italic.png ), url( images/be-tarask/button_link.png ), url( images/de/button_bold.png ), url( images/de/button_italic.png ), url( images/en/button_bold.png ), url( images/en/button_extlink.png ), url( images/en/button_headline.png ), url( images/en/button_hr.png ), url( images/en/button_image.png ), url( images/en/button_italic.png ), url( images/en/button_link.png ), url( images/en/button_media.png ), url( images/en/button_nowiki.png ), url( images/en/button_sig.png ), url( images/fa/button_bold.png ), url( images/fa/button_headline.png ), url( images/fa/button_italic.png ), url( images/fa/button_link.png ), url( images/fa/button_nowiki.png ), url( images/ksh/button_italic.png ), url( images/ru/button_bold.png ), url( images/ru/button_italic.png ), url( images/ru/button_link.png );
-}
index 45f52b7..ffb7736 100644 (file)
         * @inheritdoc
         */
        CSP.createItemWidget = function ( data ) {
+               var title = mw.Title.makeTitle( NS_CATEGORY, data );
+               if ( !title ) {
+                       return null;
+               }
                return new mw.widgets.CategoryCapsuleItemWidget( {
                        apiUrl: this.api.apiUrl || undefined,
-                       title: mw.Title.makeTitle( NS_CATEGORY, data )
+                       title: title
                } );
        };
 
        CSP.getItemFromData = function ( data ) {
                // This is a bit of a hack... We have to canonicalize the data in the same way that
                // #createItemWidget and CategoryCapsuleItemWidget will do, otherwise we won't find duplicates.
-               data = mw.Title.makeTitle( NS_CATEGORY, data ).getMainText();
-               return OO.ui.mixin.GroupElement.prototype.getItemFromData.call( this, data );
+               var title = mw.Title.makeTitle( NS_CATEGORY, data );
+               if ( !title ) {
+                       return null;
+               }
+               return OO.ui.mixin.GroupElement.prototype.getItemFromData.call( this, title.getMainText() );
        };
 
        /**
index df21eb2..9ba562e 100644 (file)
                 */
                loadMessages: function ( messages ) {
                        return this.getMessages( messages ).then( $.proxy( mw.messages, 'set' ) );
+               },
+
+               /**
+                * Loads a set of mesages and add them to mw.messages. Only messages that are not already known
+                * are loaded. If all messages are known, the returned promise is resolved immediately.
+                *
+                * @param {Array} messages Messages to retrieve
+                * @return {jQuery.Promise}
+                */
+               loadMessagesIfMissing: function ( messages ) {
+                       var missing = messages.filter( function ( msg ) {
+                               return !mw.message( msg ).exists();
+                       } );
+
+                       if ( missing.length === 0 ) {
+                               return $.Deferred().resolve();
+                       }
+
+                       return this.getMessages( missing ).then( $.proxy( mw.messages, 'set' ) );
                }
        } );
 
index bbd0f1b..31e4492 100644 (file)
                        layout.emit( 'fileUploaded' );
                }, function () {
                        // These errors will be thrown while the user is on the info page.
-                       // Pretty sure it's impossible to get a warning other than 'stashfailed' here, which should
-                       // really be an error...
-                       var errorMessage = layout.getErrorMessageForStateDetails();
-                       deferred.reject( errorMessage );
+                       layout.getErrorMessageForStateDetails().then( function ( errorMessage ) {
+                               deferred.reject( errorMessage );
+                       } );
                }, function ( progress ) {
                        var elapsedTime = new Date() - startTime,
                                estimatedTotalTime = ( 1 / progress ) * elapsedTime,
                                deferred.resolve();
                                layout.emit( 'fileSaved', layout.upload.getImageInfo() );
                        }, function () {
-                               var errorMessage = layout.getErrorMessageForStateDetails();
-                               deferred.reject( errorMessage );
+                               layout.getErrorMessageForStateDetails().then( function ( errorMessage ) {
+                                       deferred.reject( errorMessage );
+                               } );
                        } );
                } );
 
         * state and state details.
         *
         * @protected
-        * @return {OO.ui.Error} Error to display for given state and details.
+        * @return {jQuery.Promise} A Promise that will be resolved with an OO.ui.Error.
         */
        mw.Upload.BookletLayout.prototype.getErrorMessageForStateDetails = function () {
                var message,
                if ( state === mw.Upload.State.ERROR ) {
                        if ( !error ) {
                                // If there's an 'exception' key, this might be a timeout, or other connection problem
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'api-error-unknownerror', JSON.stringify( stateDetails ) ),
                                        { recoverable: false }
-                               );
+                               ) );
                        }
 
-                       // HACK We should either have a hook here to allow TitleBlacklist to handle this, or just have
-                       // TitleBlacklist produce sane error messages that can be displayed without arcane knowledge
-                       if ( error.info === 'TitleBlacklist prevents this title from being created' ) {
-                               // HACK Apparently the only reliable way to determine whether TitleBlacklist was involved
-                               return new OO.ui.Error(
-                                       // HACK TitleBlacklist doesn't have a sensible message, this one is from UploadWizard
-                                       $( '<p>' ).msg( 'api-error-blacklisted' ),
-                                       { recoverable: false }
-                               );
+                       // Errors in this format are produced by TitleBlacklist and AbuseFilter. Perhaps other
+                       // extensions will follow this format in the future.
+                       if ( error.message ) {
+                               return this.upload.getApi()
+                                       .then( function ( api ) {
+                                               return api.loadMessagesIfMissing( [ error.message.key ] ).then( function () {
+                                                       if ( !mw.message( error.message.key ).exists() ) {
+                                                               return $.Deferred().reject();
+                                                       }
+                                                       return new OO.ui.Error(
+                                                               $( '<p>' ).msg( error.message.key, error.message.params || [] ),
+                                                               { recoverable: false }
+                                                       );
+                                               } );
+                                       } )
+                                       .then( null, function () {
+                                               // We failed when loading the error message, or it doesn't actually exist, fall back
+                                               return $.Deferred().resolve( new OO.ui.Error(
+                                                       $( '<p>' ).msg( 'api-error-unknownerror', JSON.stringify( stateDetails ) ),
+                                                       { recoverable: false }
+                                               ) );
+                                       } );
                        }
 
                        if ( error.code === 'protectedpage' ) {
                                        message = mw.message( 'api-error-unknownerror', JSON.stringify( stateDetails ) );
                                }
                        }
-                       return new OO.ui.Error(
+                       return $.Deferred().resolve( new OO.ui.Error(
                                $( '<p>' ).append( message.parseDom() ),
                                { recoverable: false }
-                       );
+                       ) );
                }
 
                if ( state === mw.Upload.State.WARNING ) {
                        // of importance. For example fixing the thumbnail like file name
                        // won't help the fact that the file already exists.
                        if ( warnings.stashfailed !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'api-error-stashfailed' ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings.exists !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'fileexists', 'File:' + warnings.exists ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings[ 'exists-normalized' ] !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'fileexists', 'File:' + warnings[ 'exists-normalized' ] ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings[ 'page-exists' ] !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'filepageexists', 'File:' + warnings[ 'page-exists' ] ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings.duplicate !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'api-error-duplicate', warnings.duplicate.length ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings[ 'thumb-name' ] !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'filename-thumb-name' ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings[ 'bad-prefix' ] !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'filename-bad-prefix', warnings[ 'bad-prefix' ] ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings[ 'duplicate-archive' ] !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'api-error-duplicate-archive', 1 ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings[ 'was-deleted' ] !== undefined ) {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'api-error-was-deleted' ),
                                        { recoverable: false }
-                               );
+                               ) );
                        } else if ( warnings.badfilename !== undefined ) {
                                // Change the name if the current name isn't acceptable
                                // TODO This might not really be the best place to do this
                                this.setFilename( warnings.badfilename );
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        $( '<p>' ).msg( 'badfilename', warnings.badfilename )
-                               );
+                               ) );
                        } else {
-                               return new OO.ui.Error(
+                               return $.Deferred().resolve( new OO.ui.Error(
                                        // Let's get all the help we can if we can't pin point the error
                                        $( '<p>' ).msg( 'api-error-unknown-warning', JSON.stringify( stateDetails ) ),
                                        { recoverable: false }
-                               );
+                               ) );
                        }
                }
        };
diff --git a/resources/src/mediawiki/mediawiki.content.json.css b/resources/src/mediawiki/mediawiki.content.json.css
deleted file mode 100644 (file)
index 91fa02a..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*!
- * CSS for styling HTML-formatted JSON Schema objects
- *
- * @file
- * @author Munaf Assaf <massaf@wikimedia.org>
- */
-
-.mw-json {
-       border-collapse: collapse;
-       border-spacing: 0;
-       font-style: normal;
-}
-
-.mw-json th,
-.mw-json td {
-       border: 1px solid #808080;
-       font-size: 16px;
-       padding: 0.5em 1em;
-}
-
-.mw-json .value,
-.mw-json-single-value {
-       background-color: #dcfae3;
-       font-family: monospace, monospace;
-       white-space: pre-wrap;
-}
-
-.mw-json-single-value {
-       background-color: #eee;
-}
-
-.mw-json-empty {
-       background-color: #fff;
-       font-style: italic;
-}
-
-.mw-json tr {
-       margin-bottom: 0.5em;
-       background-color: #eee;
-}
-
-.mw-json th {
-       background-color: #fff;
-       font-weight: normal;
-}
-
-.mw-json caption {
-       /* For stylistic reasons, suppress the caption of the outermost table */
-       display: none;
-}
-
-.mw-json table caption {
-       color: #808080;
-       display: inline-block;
-       font-size: 10px;
-       font-style: italic;
-       margin-bottom: 0.5em;
-       text-align: left;
-}
diff --git a/resources/src/mediawiki/mediawiki.content.json.less b/resources/src/mediawiki/mediawiki.content.json.less
new file mode 100644 (file)
index 0000000..91fa02a
--- /dev/null
@@ -0,0 +1,59 @@
+/*!
+ * CSS for styling HTML-formatted JSON Schema objects
+ *
+ * @file
+ * @author Munaf Assaf <massaf@wikimedia.org>
+ */
+
+.mw-json {
+       border-collapse: collapse;
+       border-spacing: 0;
+       font-style: normal;
+}
+
+.mw-json th,
+.mw-json td {
+       border: 1px solid #808080;
+       font-size: 16px;
+       padding: 0.5em 1em;
+}
+
+.mw-json .value,
+.mw-json-single-value {
+       background-color: #dcfae3;
+       font-family: monospace, monospace;
+       white-space: pre-wrap;
+}
+
+.mw-json-single-value {
+       background-color: #eee;
+}
+
+.mw-json-empty {
+       background-color: #fff;
+       font-style: italic;
+}
+
+.mw-json tr {
+       margin-bottom: 0.5em;
+       background-color: #eee;
+}
+
+.mw-json th {
+       background-color: #fff;
+       font-weight: normal;
+}
+
+.mw-json caption {
+       /* For stylistic reasons, suppress the caption of the outermost table */
+       display: none;
+}
+
+.mw-json table caption {
+       color: #808080;
+       display: inline-block;
+       font-size: 10px;
+       font-style: italic;
+       margin-bottom: 0.5em;
+       text-align: left;
+}
diff --git a/resources/src/mediawiki/page/gallery-slider.js b/resources/src/mediawiki/page/gallery-slider.js
deleted file mode 100644 (file)
index 82b22e8..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-/*!
- * mw.GallerySlider: Interface controls for the slider gallery
- */
-( function ( mw, $, OO ) {
-       /**
-        * mw.GallerySlider encapsulates the user interface of the slider
-        * galleries. An object is instantiated for each `.mw-gallery-slider`
-        * element.
-        *
-        * @class mw.GallerySlider
-        * @uses mw.Title
-        * @uses mw.Api
-        * @param {jQuery} gallery The `<ul>` element of the gallery.
-        */
-       mw.GallerySlider = function ( gallery ) {
-               // Properties
-               this.$gallery = $( gallery );
-               this.$galleryCaption = this.$gallery.find( '.gallerycaption' );
-               this.$galleryBox = this.$gallery.find( '.gallerybox' );
-               this.$currentImage = null;
-               this.imageInfoCache = {};
-               if ( this.$gallery.parent().attr( 'id' ) !== 'mw-content-text' ) {
-                       this.$container = this.$gallery.parent();
-               }
-
-               // Initialize
-               this.drawCarousel();
-               this.setSizeRequirement();
-               this.toggleThumbnails( false );
-               this.showCurrentImage();
-
-               // Events
-               $( window ).on(
-                       'resize',
-                       OO.ui.debounce(
-                               this.setSizeRequirement.bind( this ),
-                               100
-                       )
-               );
-
-               // Disable thumbnails' link, instead show the image in the carousel
-               this.$galleryBox.on( 'click', function ( e ) {
-                       this.$currentImage = $( e.currentTarget );
-                       this.showCurrentImage();
-                       return false;
-               }.bind( this ) );
-       };
-
-       /* Properties */
-       /**
-        * @property {jQuery} $gallery The `<ul>` element of the gallery.
-        */
-
-       /**
-        * @property {jQuery} $galleryCaption The `<li>` that has the gallery caption.
-        */
-
-       /**
-        * @property {jQuery} $galleryBox Selection of `<li>` elements that have thumbnails.
-        */
-
-       /**
-        * @property {jQuery} $carousel The `<li>` elements that contains the carousel.
-        */
-
-       /**
-        * @property {jQuery} $interface The `<div>` elements that contains the interface buttons.
-        */
-
-       /**
-        * @property {jQuery} $img The `<img>` element that'll display the current image.
-        */
-
-       /**
-        * @property {jQuery} $imgLink The `<a>` element that links to the image's File page.
-        */
-
-       /**
-        * @property {jQuery} $imgCaption The `<p>` element that holds the image caption.
-        */
-
-       /**
-        * @property {jQuery} $imgContainer The `<div>` element that contains the image.
-        */
-
-       /**
-        * @property {jQuery} $currentImage The `<li>` element of the current image.
-        */
-
-       /**
-        * @property {jQuery} $container If the gallery contained in an element that is
-        *      not the main content element, then it stores that element.
-        */
-
-       /**
-        * @property {Object} imageInfoCache A key value pair of thumbnail URLs and image info.
-        */
-
-       /**
-        * @property {number} imageWidth Width of the image based on viewport size
-        */
-
-       /**
-        * @property {number} imageHeight Height of the image based on viewport size
-        *      the URLs in the required size.
-        */
-
-       /* Setup */
-       OO.initClass( mw.GallerySlider );
-
-       /* Methods */
-       /**
-        * Draws the carousel and the interface around it.
-        */
-       mw.GallerySlider.prototype.drawCarousel = function () {
-               var next, prev, toggle, interfaceElements, carouselStack;
-
-               this.$carousel = $( '<li>' ).addClass( 'gallerycarousel' );
-
-               // Buttons for the interface
-               prev = new OO.ui.ButtonWidget( {
-                       framed: false,
-                       icon: 'previous'
-               } ).on( 'click', this.prevImage.bind( this ) );
-
-               next = new OO.ui.ButtonWidget( {
-                       framed: false,
-                       icon: 'next'
-               } ).on( 'click', this.nextImage.bind( this ) );
-
-               toggle = new OO.ui.ButtonWidget( {
-                       framed: false,
-                       icon: 'imageGallery'
-               } ).on( 'click', this.toggleThumbnails.bind( this ) );
-
-               interfaceElements = new OO.ui.PanelLayout( {
-                       expanded: false,
-                       classes: [ 'mw-gallery-slider-buttons' ],
-                       $content: $( '<div>' ).append(
-                               prev.$element,
-                               toggle.$element,
-                               next.$element
-                       )
-               } );
-               this.$interface = interfaceElements.$element;
-
-               // Containers for the current image, caption etc.
-               this.$img = $( '<img>' );
-               this.$imgLink = $( '<a>' ).append( this.$img );
-               this.$imgCaption = $( '<p>' ).attr( 'class', 'mw-gallery-slider-caption' );
-               this.$imgContainer = $( '<div>' )
-                       .attr( 'class', 'mw-gallery-slider-img-container' )
-                       .append( this.$imgLink );
-
-               carouselStack = new OO.ui.StackLayout( {
-                       continuous: true,
-                       expanded: false,
-                       items: [
-                               interfaceElements,
-                               new OO.ui.PanelLayout( {
-                                       expanded: false,
-                                       $content: this.$imgContainer
-                               } ),
-                               new OO.ui.PanelLayout( {
-                                       expanded: false,
-                                       $content: this.$imgCaption
-                               } )
-                       ]
-               } );
-               this.$carousel.append( carouselStack.$element );
-
-               // Append below the caption or as the first element in the gallery
-               if ( this.$galleryCaption.length !== 0 ) {
-                       this.$galleryCaption.after( this.$carousel );
-               } else {
-                       this.$gallery.prepend( this.$carousel );
-               }
-       };
-
-       /**
-        * Sets the {@link #imageWidth} and {@link #imageHeight} properties
-        * based on the size of the window. Also flushes the
-        * {@link #imageInfoCache} as we'll now need URLs for a different
-        * size.
-        */
-       mw.GallerySlider.prototype.setSizeRequirement = function () {
-               var w, h;
-
-               if ( this.$container !== undefined ) {
-                       w = this.$container.width() * 0.9;
-                       h = ( this.$container.height() - this.getChromeHeight() ) * 0.9;
-               } else {
-                       w = this.$imgContainer.width();
-                       h = Math.min( $( window ).height() * ( 3 / 4 ), this.$imgContainer.width() ) - this.getChromeHeight();
-               }
-
-               // Only update and flush the cache if the size changed
-               if ( w !== this.imageWidth || h !== this.imageHeight ) {
-                       this.imageWidth = w;
-                       this.imageHeight = h;
-                       this.imageInfoCache = {};
-                       this.setImageSize();
-               }
-       };
-
-       /**
-        * Gets the height of the interface elements and the
-        * gallery's caption.
-        */
-       mw.GallerySlider.prototype.getChromeHeight = function () {
-               return this.$interface.outerHeight() + this.$galleryCaption.outerHeight();
-       };
-
-       /**
-        * Sets the height and width of {@link #$img} based on the
-        * proportion of the image and the values generated by
-        * {@link #setSizeRequirement}.
-        *
-        * @return {boolean} Whether or not the image was sized.
-        */
-       mw.GallerySlider.prototype.setImageSize = function () {
-               if ( this.$img === undefined || this.$thumbnail === undefined ) {
-                       return false;
-               }
-
-               // Reset height and width
-               this.$img
-                       .removeAttr( 'width' )
-                       .removeAttr( 'height' );
-
-               // Stretch image to take up the required size
-               if ( this.$thumbnail.width() > this.$thumbnail.height() ) {
-                       this.$img.attr( 'width', this.imageWidth + 'px' );
-               } else {
-                       this.$img.attr( 'height', this.imageHeight + 'px' );
-               }
-
-               // Make the image smaller in case the current image
-               // size is larger than the original file size.
-               this.getImageInfo( this.$thumbnail ).done( function ( info ) {
-                       // NOTE: There will be a jump when resizing the window
-                       // because the cache is cleared and this a new network request.
-                       if (
-                               info.thumbwidth < this.$img.width() ||
-                               info.thumbheight < this.$img.height()
-                       ) {
-                               this.$img.attr( 'width', info.thumbwidth + 'px' );
-                               this.$img.attr( 'height', info.thumbheight + 'px' );
-                       }
-               }.bind( this ) );
-
-               return true;
-       };
-
-       /**
-        * Displays the image set as {@link #$currentImage} in the carousel.
-        */
-       mw.GallerySlider.prototype.showCurrentImage = function () {
-               var imageLi = this.getCurrentImage(),
-                       caption = imageLi.find( '.gallerytext' );
-
-               // Highlight current thumbnail
-               this.$gallery
-                       .find( '.gallerybox.slider-current' )
-                       .removeClass( 'slider-current' );
-               imageLi.addClass( 'slider-current' );
-
-               // Show thumbnail stretched to the right size while the image loads
-               this.$thumbnail = imageLi.find( 'img' );
-               this.$img.attr( 'src', this.$thumbnail.attr( 'src' ) );
-               this.$imgLink.attr( 'href', imageLi.find( 'a' ).eq( 0 ).attr( 'href' ) );
-               this.setImageSize();
-
-               // Copy caption
-               this.$imgCaption
-                       .empty()
-                       .append( caption.clone() );
-
-               // Load image at the required size
-               this.loadImage( this.$thumbnail ).done( function ( info, $img ) {
-                       // Show this image to the user only if its still the current one
-                       if ( this.$thumbnail.attr( 'src' ) === $img.attr( 'src' ) ) {
-                               this.$img.attr( 'src', info.thumburl );
-                               this.setImageSize();
-
-                               // Keep the next image ready
-                               this.loadImage( this.getNextImage().find( 'img' ) );
-                       }
-               }.bind( this ) );
-       };
-
-       /**
-        * Loads the full image given the `<img>` element of the thumbnail.
-        *
-        * @param {Object} $img
-        * @return {jQuery.Promise} Resolves with the images URL and original
-        *      element once the image has loaded.
-        */
-       mw.GallerySlider.prototype.loadImage = function ( $img ) {
-               var img, d = $.Deferred();
-
-               this.getImageInfo( $img ).done( function ( info ) {
-                       img = new Image();
-                       img.src = info.thumburl;
-                       img.onload = function () {
-                               d.resolve( info, $img );
-                       };
-                       img.onerror = function () {
-                               d.reject();
-                       };
-               } ).fail( function () {
-                       d.reject();
-               } );
-
-               return d.promise();
-       };
-
-       /**
-        * Gets the image's info given an `<img>` element.
-        *
-        * @param {Object} $img
-        * @return {jQuery.Promise} Resolves with the image's info.
-        */
-       mw.GallerySlider.prototype.getImageInfo = function ( $img ) {
-               var api, title, params,
-                       imageSrc = $img.attr( 'src' );
-
-               if ( this.imageInfoCache[ imageSrc ] === undefined ) {
-                       api = new mw.Api();
-                       // TODO: This supports only gallery of images
-                       title = new mw.Title.newFromImg( $img );
-                       params = {
-                               action: 'query',
-                               formatversion: 2,
-                               titles: title.toString(),
-                               prop: 'imageinfo',
-                               iiprop: 'url'
-                       };
-
-                       // Check which dimension we need to request, based on
-                       // image and container proportions.
-                       if ( this.getDimensionToRequest( $img ) === 'height' ) {
-                               params.iiurlheight = this.imageHeight;
-                       } else {
-                               params.iiurlwidth = this.imageWidth;
-                       }
-
-                       this.imageInfoCache[ imageSrc ] = api.get( params ).then( function ( data ) {
-                               if ( OO.getProp( data, 'query', 'pages', 0, 'imageinfo', 0, 'thumburl' ) !== undefined ) {
-                                       return data.query.pages[ 0 ].imageinfo[ 0 ];
-                               } else {
-                                       return $.Deferred().reject();
-                               }
-                       } );
-               }
-
-               return this.imageInfoCache[ imageSrc ];
-       };
-
-       /**
-        * Given an image, the method checks whether to use the height
-        * or the width to request the larger image.
-        *
-        * @param {jQuery} $img
-        * @return {string}
-        */
-       mw.GallerySlider.prototype.getDimensionToRequest = function ( $img ) {
-               var ratio = $img.width() / $img.height();
-
-               if ( this.imageHeight * ratio <= this.imageWidth ) {
-                       return 'height';
-               } else {
-                       return 'width';
-               }
-       };
-
-       /**
-        * Toggles visibility of the thumbnails.
-        *
-        * @param {boolean} show Optional argument to control the state
-        */
-       mw.GallerySlider.prototype.toggleThumbnails = function ( show ) {
-               this.$galleryBox.toggle( show );
-               this.$carousel.toggleClass( 'mw-gallery-slider-thumbnails-toggled', show );
-       };
-
-       /**
-        * Getter method for {@link #$currentImage}
-        *
-        * @return {jQuery}
-        */
-       mw.GallerySlider.prototype.getCurrentImage = function () {
-               this.$currentImage = this.$currentImage || this.$galleryBox.eq( 0 );
-               return this.$currentImage;
-       };
-
-       /**
-        * Gets the image after the current one. Returns the first image if
-        * the current one is the last.
-        *
-        * @return {jQuery}
-        */
-       mw.GallerySlider.prototype.getNextImage = function () {
-               // Not the last image in the gallery
-               if ( this.$currentImage.next( '.gallerybox' )[ 0 ] !== undefined ) {
-                       return this.$currentImage.next( '.gallerybox' );
-               } else {
-                       return this.$galleryBox.eq( 0 );
-               }
-       };
-
-       /**
-        * Gets the image before the current one. Returns the last image if
-        * the current one is the first.
-        *
-        * @return {jQuery}
-        */
-       mw.GallerySlider.prototype.getPrevImage = function () {
-               // Not the first image in the gallery
-               if ( this.$currentImage.prev( '.gallerybox' )[ 0 ] !== undefined ) {
-                       return this.$currentImage.prev( '.gallerybox' );
-               } else {
-                       return this.$galleryBox.last();
-               }
-       };
-
-       /**
-        * Sets the {@link #$currentImage} to the next one and shows
-        * it in the carousel
-        */
-       mw.GallerySlider.prototype.nextImage = function () {
-               this.$currentImage = this.getNextImage();
-               this.showCurrentImage();
-       };
-
-       /**
-        * Sets the {@link #$currentImage} to the previous one and shows
-        * it in the carousel
-        */
-       mw.GallerySlider.prototype.prevImage = function () {
-               this.$currentImage = this.getPrevImage();
-               this.showCurrentImage();
-       };
-
-       // Bootstrap all slider galleries
-       $( function () {
-               $( '.mw-gallery-slider' ).each( function () {
-                       /*jshint -W031 */
-                       new mw.GallerySlider( this );
-                       /*jshint +W031 */
-               } );
-       } );
-}( mediaWiki, jQuery, OO ) );
diff --git a/resources/src/mediawiki/page/gallery-slideshow.js b/resources/src/mediawiki/page/gallery-slideshow.js
new file mode 100644 (file)
index 0000000..85ded44
--- /dev/null
@@ -0,0 +1,453 @@
+/*!
+ * mw.GallerySlideshow: Interface controls for the slideshow gallery
+ */
+( function ( mw, $, OO ) {
+       /**
+        * mw.GallerySlideshow encapsulates the user interface of the slideshow
+        * galleries. An object is instantiated for each `.mw-gallery-slideshow`
+        * element.
+        *
+        * @class mw.GallerySlideshow
+        * @uses mw.Title
+        * @uses mw.Api
+        * @param {jQuery} gallery The `<ul>` element of the gallery.
+        */
+       mw.GallerySlideshow = function ( gallery ) {
+               // Properties
+               this.$gallery = $( gallery );
+               this.$galleryCaption = this.$gallery.find( '.gallerycaption' );
+               this.$galleryBox = this.$gallery.find( '.gallerybox' );
+               this.$currentImage = null;
+               this.imageInfoCache = {};
+               if ( this.$gallery.parent().attr( 'id' ) !== 'mw-content-text' ) {
+                       this.$container = this.$gallery.parent();
+               }
+
+               // Initialize
+               this.drawCarousel();
+               this.setSizeRequirement();
+               this.toggleThumbnails( false );
+               this.showCurrentImage();
+
+               // Events
+               $( window ).on(
+                       'resize',
+                       OO.ui.debounce(
+                               this.setSizeRequirement.bind( this ),
+                               100
+                       )
+               );
+
+               // Disable thumbnails' link, instead show the image in the carousel
+               this.$galleryBox.on( 'click', function ( e ) {
+                       this.$currentImage = $( e.currentTarget );
+                       this.showCurrentImage();
+                       return false;
+               }.bind( this ) );
+       };
+
+       /* Properties */
+       /**
+        * @property {jQuery} $gallery The `<ul>` element of the gallery.
+        */
+
+       /**
+        * @property {jQuery} $galleryCaption The `<li>` that has the gallery caption.
+        */
+
+       /**
+        * @property {jQuery} $galleryBox Selection of `<li>` elements that have thumbnails.
+        */
+
+       /**
+        * @property {jQuery} $carousel The `<li>` elements that contains the carousel.
+        */
+
+       /**
+        * @property {jQuery} $interface The `<div>` elements that contains the interface buttons.
+        */
+
+       /**
+        * @property {jQuery} $img The `<img>` element that'll display the current image.
+        */
+
+       /**
+        * @property {jQuery} $imgLink The `<a>` element that links to the image's File page.
+        */
+
+       /**
+        * @property {jQuery} $imgCaption The `<p>` element that holds the image caption.
+        */
+
+       /**
+        * @property {jQuery} $imgContainer The `<div>` element that contains the image.
+        */
+
+       /**
+        * @property {jQuery} $currentImage The `<li>` element of the current image.
+        */
+
+       /**
+        * @property {jQuery} $container If the gallery contained in an element that is
+        *      not the main content element, then it stores that element.
+        */
+
+       /**
+        * @property {Object} imageInfoCache A key value pair of thumbnail URLs and image info.
+        */
+
+       /**
+        * @property {number} imageWidth Width of the image based on viewport size
+        */
+
+       /**
+        * @property {number} imageHeight Height of the image based on viewport size
+        *      the URLs in the required size.
+        */
+
+       /* Setup */
+       OO.initClass( mw.GallerySlideshow );
+
+       /* Methods */
+       /**
+        * Draws the carousel and the interface around it.
+        */
+       mw.GallerySlideshow.prototype.drawCarousel = function () {
+               var next, prev, toggle, interfaceElements, carouselStack;
+
+               this.$carousel = $( '<li>' ).addClass( 'gallerycarousel' );
+
+               // Buttons for the interface
+               prev = new OO.ui.ButtonWidget( {
+                       framed: false,
+                       icon: 'previous'
+               } ).on( 'click', this.prevImage.bind( this ) );
+
+               next = new OO.ui.ButtonWidget( {
+                       framed: false,
+                       icon: 'next'
+               } ).on( 'click', this.nextImage.bind( this ) );
+
+               toggle = new OO.ui.ButtonWidget( {
+                       framed: false,
+                       icon: 'imageGallery'
+               } ).on( 'click', this.toggleThumbnails.bind( this ) );
+
+               interfaceElements = new OO.ui.PanelLayout( {
+                       expanded: false,
+                       classes: [ 'mw-gallery-slideshow-buttons' ],
+                       $content: $( '<div>' ).append(
+                               prev.$element,
+                               toggle.$element,
+                               next.$element
+                       )
+               } );
+               this.$interface = interfaceElements.$element;
+
+               // Containers for the current image, caption etc.
+               this.$img = $( '<img>' );
+               this.$imgLink = $( '<a>' ).append( this.$img );
+               this.$imgCaption = $( '<p>' ).attr( 'class', 'mw-gallery-slideshow-caption' );
+               this.$imgContainer = $( '<div>' )
+                       .attr( 'class', 'mw-gallery-slideshow-img-container' )
+                       .append( this.$imgLink );
+
+               carouselStack = new OO.ui.StackLayout( {
+                       continuous: true,
+                       expanded: false,
+                       items: [
+                               interfaceElements,
+                               new OO.ui.PanelLayout( {
+                                       expanded: false,
+                                       $content: this.$imgContainer
+                               } ),
+                               new OO.ui.PanelLayout( {
+                                       expanded: false,
+                                       $content: this.$imgCaption
+                               } )
+                       ]
+               } );
+               this.$carousel.append( carouselStack.$element );
+
+               // Append below the caption or as the first element in the gallery
+               if ( this.$galleryCaption.length !== 0 ) {
+                       this.$galleryCaption.after( this.$carousel );
+               } else {
+                       this.$gallery.prepend( this.$carousel );
+               }
+       };
+
+       /**
+        * Sets the {@link #imageWidth} and {@link #imageHeight} properties
+        * based on the size of the window. Also flushes the
+        * {@link #imageInfoCache} as we'll now need URLs for a different
+        * size.
+        */
+       mw.GallerySlideshow.prototype.setSizeRequirement = function () {
+               var w, h;
+
+               if ( this.$container !== undefined ) {
+                       w = this.$container.width() * 0.9;
+                       h = ( this.$container.height() - this.getChromeHeight() ) * 0.9;
+               } else {
+                       w = this.$imgContainer.width();
+                       h = Math.min( $( window ).height() * ( 3 / 4 ), this.$imgContainer.width() ) - this.getChromeHeight();
+               }
+
+               // Only update and flush the cache if the size changed
+               if ( w !== this.imageWidth || h !== this.imageHeight ) {
+                       this.imageWidth = w;
+                       this.imageHeight = h;
+                       this.imageInfoCache = {};
+                       this.setImageSize();
+               }
+       };
+
+       /**
+        * Gets the height of the interface elements and the
+        * gallery's caption.
+        */
+       mw.GallerySlideshow.prototype.getChromeHeight = function () {
+               return this.$interface.outerHeight() + this.$galleryCaption.outerHeight();
+       };
+
+       /**
+        * Sets the height and width of {@link #$img} based on the
+        * proportion of the image and the values generated by
+        * {@link #setSizeRequirement}.
+        *
+        * @return {boolean} Whether or not the image was sized.
+        */
+       mw.GallerySlideshow.prototype.setImageSize = function () {
+               if ( this.$img === undefined || this.$thumbnail === undefined ) {
+                       return false;
+               }
+
+               // Reset height and width
+               this.$img
+                       .removeAttr( 'width' )
+                       .removeAttr( 'height' );
+
+               // Stretch image to take up the required size
+               if ( this.$thumbnail.width() > this.$thumbnail.height() ) {
+                       this.$img.attr( 'width', this.imageWidth + 'px' );
+               } else {
+                       this.$img.attr( 'height', this.imageHeight + 'px' );
+               }
+
+               // Make the image smaller in case the current image
+               // size is larger than the original file size.
+               this.getImageInfo( this.$thumbnail ).done( function ( info ) {
+                       // NOTE: There will be a jump when resizing the window
+                       // because the cache is cleared and this a new network request.
+                       if (
+                               info.thumbwidth < this.$img.width() ||
+                               info.thumbheight < this.$img.height()
+                       ) {
+                               this.$img.attr( 'width', info.thumbwidth + 'px' );
+                               this.$img.attr( 'height', info.thumbheight + 'px' );
+                       }
+               }.bind( this ) );
+
+               return true;
+       };
+
+       /**
+        * Displays the image set as {@link #$currentImage} in the carousel.
+        */
+       mw.GallerySlideshow.prototype.showCurrentImage = function () {
+               var imageLi = this.getCurrentImage(),
+                       caption = imageLi.find( '.gallerytext' );
+
+               // Highlight current thumbnail
+               this.$gallery
+                       .find( '.gallerybox.slideshow-current' )
+                       .removeClass( 'slideshow-current' );
+               imageLi.addClass( 'slideshow-current' );
+
+               // Show thumbnail stretched to the right size while the image loads
+               this.$thumbnail = imageLi.find( 'img' );
+               this.$img.attr( 'src', this.$thumbnail.attr( 'src' ) );
+               this.$imgLink.attr( 'href', imageLi.find( 'a' ).eq( 0 ).attr( 'href' ) );
+               this.setImageSize();
+
+               // Copy caption
+               this.$imgCaption
+                       .empty()
+                       .append( caption.clone() );
+
+               // Load image at the required size
+               this.loadImage( this.$thumbnail ).done( function ( info, $img ) {
+                       // Show this image to the user only if its still the current one
+                       if ( this.$thumbnail.attr( 'src' ) === $img.attr( 'src' ) ) {
+                               this.$img.attr( 'src', info.thumburl );
+                               this.setImageSize();
+
+                               // Keep the next image ready
+                               this.loadImage( this.getNextImage().find( 'img' ) );
+                       }
+               }.bind( this ) );
+       };
+
+       /**
+        * Loads the full image given the `<img>` element of the thumbnail.
+        *
+        * @param {Object} $img
+        * @return {jQuery.Promise} Resolves with the images URL and original
+        *      element once the image has loaded.
+        */
+       mw.GallerySlideshow.prototype.loadImage = function ( $img ) {
+               var img, d = $.Deferred();
+
+               this.getImageInfo( $img ).done( function ( info ) {
+                       img = new Image();
+                       img.src = info.thumburl;
+                       img.onload = function () {
+                               d.resolve( info, $img );
+                       };
+                       img.onerror = function () {
+                               d.reject();
+                       };
+               } ).fail( function () {
+                       d.reject();
+               } );
+
+               return d.promise();
+       };
+
+       /**
+        * Gets the image's info given an `<img>` element.
+        *
+        * @param {Object} $img
+        * @return {jQuery.Promise} Resolves with the image's info.
+        */
+       mw.GallerySlideshow.prototype.getImageInfo = function ( $img ) {
+               var api, title, params,
+                       imageSrc = $img.attr( 'src' );
+
+               if ( this.imageInfoCache[ imageSrc ] === undefined ) {
+                       api = new mw.Api();
+                       // TODO: This supports only gallery of images
+                       title = new mw.Title.newFromImg( $img );
+                       params = {
+                               action: 'query',
+                               formatversion: 2,
+                               titles: title.toString(),
+                               prop: 'imageinfo',
+                               iiprop: 'url'
+                       };
+
+                       // Check which dimension we need to request, based on
+                       // image and container proportions.
+                       if ( this.getDimensionToRequest( $img ) === 'height' ) {
+                               params.iiurlheight = this.imageHeight;
+                       } else {
+                               params.iiurlwidth = this.imageWidth;
+                       }
+
+                       this.imageInfoCache[ imageSrc ] = api.get( params ).then( function ( data ) {
+                               if ( OO.getProp( data, 'query', 'pages', 0, 'imageinfo', 0, 'thumburl' ) !== undefined ) {
+                                       return data.query.pages[ 0 ].imageinfo[ 0 ];
+                               } else {
+                                       return $.Deferred().reject();
+                               }
+                       } );
+               }
+
+               return this.imageInfoCache[ imageSrc ];
+       };
+
+       /**
+        * Given an image, the method checks whether to use the height
+        * or the width to request the larger image.
+        *
+        * @param {jQuery} $img
+        * @return {string}
+        */
+       mw.GallerySlideshow.prototype.getDimensionToRequest = function ( $img ) {
+               var ratio = $img.width() / $img.height();
+
+               if ( this.imageHeight * ratio <= this.imageWidth ) {
+                       return 'height';
+               } else {
+                       return 'width';
+               }
+       };
+
+       /**
+        * Toggles visibility of the thumbnails.
+        *
+        * @param {boolean} show Optional argument to control the state
+        */
+       mw.GallerySlideshow.prototype.toggleThumbnails = function ( show ) {
+               this.$galleryBox.toggle( show );
+               this.$carousel.toggleClass( 'mw-gallery-slideshow-thumbnails-toggled', show );
+       };
+
+       /**
+        * Getter method for {@link #$currentImage}
+        *
+        * @return {jQuery}
+        */
+       mw.GallerySlideshow.prototype.getCurrentImage = function () {
+               this.$currentImage = this.$currentImage || this.$galleryBox.eq( 0 );
+               return this.$currentImage;
+       };
+
+       /**
+        * Gets the image after the current one. Returns the first image if
+        * the current one is the last.
+        *
+        * @return {jQuery}
+        */
+       mw.GallerySlideshow.prototype.getNextImage = function () {
+               // Not the last image in the gallery
+               if ( this.$currentImage.next( '.gallerybox' )[ 0 ] !== undefined ) {
+                       return this.$currentImage.next( '.gallerybox' );
+               } else {
+                       return this.$galleryBox.eq( 0 );
+               }
+       };
+
+       /**
+        * Gets the image before the current one. Returns the last image if
+        * the current one is the first.
+        *
+        * @return {jQuery}
+        */
+       mw.GallerySlideshow.prototype.getPrevImage = function () {
+               // Not the first image in the gallery
+               if ( this.$currentImage.prev( '.gallerybox' )[ 0 ] !== undefined ) {
+                       return this.$currentImage.prev( '.gallerybox' );
+               } else {
+                       return this.$galleryBox.last();
+               }
+       };
+
+       /**
+        * Sets the {@link #$currentImage} to the next one and shows
+        * it in the carousel
+        */
+       mw.GallerySlideshow.prototype.nextImage = function () {
+               this.$currentImage = this.getNextImage();
+               this.showCurrentImage();
+       };
+
+       /**
+        * Sets the {@link #$currentImage} to the previous one and shows
+        * it in the carousel
+        */
+       mw.GallerySlideshow.prototype.prevImage = function () {
+               this.$currentImage = this.getPrevImage();
+               this.showCurrentImage();
+       };
+
+       // Bootstrap all slideshow galleries
+       $( function () {
+               $( '.mw-gallery-slideshow' ).each( function () {
+                       /*jshint -W031 */
+                       new mw.GallerySlideshow( this );
+                       /*jshint +W031 */
+               } );
+       } );
+}( mediaWiki, jQuery, OO ) );
index 7bf0f81..dabf475 100644 (file)
@@ -45,6 +45,16 @@ div.gallerytext {
        word-wrap: break-word;
 }
 
+.galleryfilename {
+       display: block;
+}
+
+.galleryfilename-truncate {
+       white-space: nowrap;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+
 /* new gallery stuff */
 ul.mw-gallery-nolines li.gallerybox div.thumb {
        background-color: transparent;
@@ -125,48 +135,48 @@ ul.mw-gallery-packed {
        text-align: center;
 }
 
-/* Slider */
-ul.gallery.mw-gallery-slider {
+/* Slideshow */
+ul.gallery.mw-gallery-slideshow {
        display: block;
        margin: 4em 0;
 }
 
-ul.gallery.mw-gallery-slider .gallerycaption {
+ul.gallery.mw-gallery-slideshow .gallerycaption {
        font-size: 1.3em;
        margin: 0;
 }
 
-ul.gallery.mw-gallery-slider .gallerycarousel.mw-gallery-slider-thumbnails-toggled {
+ul.gallery.mw-gallery-slideshow .gallerycarousel.mw-gallery-slideshow-thumbnails-toggled {
        margin-bottom: 1.3em;
 }
 
-ul.gallery.mw-gallery-slider .mw-gallery-slider-buttons {
+ul.gallery.mw-gallery-slideshow .mw-gallery-slideshow-buttons {
        opacity: 0.5;
        padding: 1.3em 0;
 }
 
-ul.gallery.mw-gallery-slider .mw-gallery-slider-buttons .oo-ui-buttonElement {
+ul.gallery.mw-gallery-slideshow .mw-gallery-slideshow-buttons .oo-ui-buttonElement {
        margin: 0 2em;
 }
 
-.mw-gallery-slider li.gallerybox.slider-current {
+.mw-gallery-slideshow li.gallerybox.slideshow-current {
        background: #efefef;
 }
 
-.mw-gallery-slider .gallerybox > div {
+.mw-gallery-slideshow .gallerybox > div {
        max-width: 120px;
 }
 
-ul.mw-gallery-slider li.gallerybox div.thumb {
+ul.mw-gallery-slideshow li.gallerybox div.thumb {
        border: none;
        background: transparent;
 }
 
-ul.mw-gallery-slider li.gallerycarousel {
+ul.mw-gallery-slideshow li.gallerycarousel {
        display: block;
        text-align: center;
 }
 
-.mw-gallery-slider-img-container a {
+.mw-gallery-slideshow-img-container a {
        display: block;
-}
\ No newline at end of file
+}
index cd37e33..282799a 100644 (file)
@@ -1,10 +1,5 @@
 ( function ( mw, $ ) {
 
-       // Support: MediaWiki < 1.26
-       // Cached HTML will not yet have this from OutputPage::getHeadScripts.
-       document.documentElement.className = document.documentElement.className
-               .replace( /(^|\s)client-nojs(\s|$)/, '$1client-js$2' );
-
        mw.page = {};
 
        $( function () {
index d602194..9adc3e6 100644 (file)
@@ -164,7 +164,7 @@ class ParserTest {
                $this->runParsoid = isset( $options['run-parsoid'] );
 
                $this->djVuSupport = new DjVuSupport();
-               $this->tidySupport = new TidySupport();
+               $this->tidySupport = new TidySupport( isset( $options['use-tidy-config'] ) );
                if ( !$this->tidySupport->isEnabled() ) {
                        echo "Warning: tidy is not installed, skipping some tests\n";
                }
@@ -854,8 +854,6 @@ class ParserTest {
         * @return RequestContext
         */
        private function setupGlobals( $opts = '', $config = '' ) {
-               global $IP;
-
                # Find out values for some special options.
                $lang =
                        self::getOptionValue( 'language', $opts, 'en' );
@@ -939,12 +937,8 @@ class ParserTest {
                        'wgDisableLangConversion' => false,
                        'wgDisableTitleConversion' => false,
                        // Tidy options.
-                       'wgUseTidy' => isset( $opts['tidy'] ),
-                       'wgTidyConfig' => null,
-                       'wgDebugTidy' => false,
-                       'wgTidyConf' => $IP . '/includes/tidy/tidy.conf',
-                       'wgTidyOpts' => '',
-                       'wgTidyInternal' => $this->tidySupport->isInternal(),
+                       'wgUseTidy' => false,
+                       'wgTidyConfig' => isset( $opts['tidy'] ) ? $this->tidySupport->getConfig() : null
                ];
 
                if ( $config ) {
index f45c666..d6d2b29 100644 (file)
@@ -35,7 +35,7 @@
 #
 # You can also set the following parser properties via test options:
 #  wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel,
-#  wgLinkHolderBatchSize, wgRawHtml
+#  wgLinkHolderBatchSize, wgRawHtml, wgInterwikiMagic
 #
 # For testing purposes, temporary articles can created:
 # !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle
@@ -8361,6 +8361,7 @@ Blah blah blah
 <link rel="mw:PageProp/Language" href="http://zh.wikipedia.org/wiki/Chinese"/>
 !! end
 
+## parsoid html2wt will lose the space variations
 !! test
 Interlanguage link with spacing
 !! options
@@ -8391,6 +8392,7 @@ Blah blah blah
 <link rel="mw:PageProp/Language" href="http://zh.wikipedia.org/wiki/Chinese"/>
 !! end
 
+## parsoid html2wt will lose the space variations
 !! test
 Interlanguage link variations
 !! options
@@ -8410,6 +8412,7 @@ Blah blah blah
 <link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Foo_bar" />
 !! end
 
+## parsoid html2wt will normalize the space to _
 !! test
 Space and question mark encoding in interlanguage links (T95473)
 !! options
@@ -8470,6 +8473,34 @@ Blah blah blah
 <link rel="mw:PageProp/Language" title="Multilingual" href="http://wikisource.org/wiki/Article"/>
 !! end
 
+## PHP parser tests script needs an update
+## Parsoid html2wt will normalize output to [[:zh:Chinese]]
+!! test
+Language links render as inline links if $wgInterwikiMagic=false
+!! options
+wgInterwikiMagic=false
+parsoid=wt2html,wt2wt,html2html
+!! wikitext
+Blah blah blah
+[[zh:Chinese]]
+!! html/parsoid
+<p>Blah blah blah <a rel="mw:ExtLink" href="http://zh.wikipedia.org/wiki/Chinese" title="zh:Chinese">zh:Chinese</a></p>
+!! end
+
+## PHP parser tests script needs an update
+## Parsoid html2wt will normalize output to [[:zh:Chinese]]
+!! test
+Language links render as inline links in the Talk namespace
+!! options
+title=Talk:Foo
+parsoid=wt2html,wt2wt,html2html
+!! wikitext
+Blah blah blah
+[[zh:Chinese]]
+!! html/parsoid
+<p>Blah blah blah <a rel="mw:ExtLink" href="http://zh.wikipedia.org/wiki/Chinese" title="zh:Chinese">zh:Chinese</a></p>
+!! end
+
 !! test
 Parsoid-specific test: Wikilinks with &nbsp; should RT properly
 !! options
@@ -18827,7 +18858,7 @@ File:Foobar.jpg
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
                        <div class="thumb" style="height: 150px;">Nonexistent.jpg</div>
                        <div class="gallerytext">
-<p><a href="/wiki/File:Nonexistent.jpg" title="File:Nonexistent.jpg">Nonexistent.jpg</a><br />
+<p><a href="/wiki/File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">Nonexistent.jpg</a>
 caption
 </p>
                        </div>
@@ -18835,14 +18866,14 @@ caption
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
                        <div class="thumb" style="height: 150px;">Nonexistent.jpg</div>
                        <div class="gallerytext">
-<p><a href="/wiki/File:Nonexistent.jpg" title="File:Nonexistent.jpg">Nonexistent.jpg</a><br />
+<p><a href="/wiki/File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">Nonexistent.jpg</a>
 </p>
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
                        <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
                        <div class="gallerytext">
-<p><a href="/wiki/File:Foobar.jpg" title="File:Foobar.jpg">Foobar.jpg</a><br />
+<p><a href="/wiki/File:Foobar.jpg" class="galleryfilename galleryfilename-truncate" title="File:Foobar.jpg">Foobar.jpg</a>
 some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a>
 </p>
                        </div>
@@ -18850,7 +18881,7 @@ some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
                        <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
                        <div class="gallerytext">
-<p><a href="/wiki/File:Foobar.jpg" title="File:Foobar.jpg">Foobar.jpg</a><br />
+<p><a href="/wiki/File:Foobar.jpg" class="galleryfilename galleryfilename-truncate" title="File:Foobar.jpg">Foobar.jpg</a>
 </p>
                        </div>
                </div></li>
@@ -27065,6 +27096,21 @@ B <ref group="X" name="b" />
 </references>
 !! end
 
+!! test
+DOMDiff: Edits to content nested in elements with templated attributes should not be lost (T139388)
+!! options
+parsoid={
+  "modes": ["selser"],
+  "changes": [
+    [ "div:first-child", "text", "bar" ]
+  ]
+}
+!! wikitext
+<div style="{{1x|color:red;}}%">foo</div>
+!! wikitext/edited
+<div style="{{1x|color:red;}}%">bar</div>
+!! end
+
 !! test
 Empty LI (T49673)
 !! wikitext
@@ -27075,8 +27121,22 @@ Empty LI (T49673)
 !! html/php+tidy
 <ul>
 <li>a</li>
-<li class="mw-empty-li"></li>
-<li class="mw-empty-li"></li>
+<li class="mw-empty-elt"></li>
+<li class="mw-empty-elt"></li>
 <li>b</li>
 </ul>
 !! end
+
+!! test
+Thumbnail output
+!! wikitext
+[[File:Thumb.png|thumb]]
+!! html/php+tidy
+<div class="thumb tright">
+<div class="thumbinner" style="width:137px;"><a href="/wiki/File:Thumb.png" class="image"><img alt="Thumb.png" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a>
+<div class="thumbcaption">
+<div class="magnify"><a href="/wiki/File:Thumb.png" class="internal" title="Enlarge"></a></div>
+</div>
+</div>
+</div>
+!! end
index 5e15694..f961dd4 100644 (file)
@@ -63,6 +63,8 @@ Options:
                    irrelevant differences. The accepted normalization functions
                    are: removeTbody to remove <tbody> tags; and trimWhitespace
                    to trim whitespace from the start and end of text nodes.
+  --use-tidy-config Use the wiki's Tidy configuration instead of known-good
+                   defaults.
   --help           Show this help message
 
 ENDS;
index a2bb97a..a5d3570 100644 (file)
@@ -30,14 +30,14 @@ class ExportTest extends MediaWikiLangTestCase {
 
                $title = Title::newFromText( $pageTitle );
 
-               ob_start();
+               $sink = new DumpStringOutput;
+               $exporter->setOutputSink( $sink );
                $exporter->openStream();
                $exporter->pageByTitle( $title );
                $exporter->closeStream();
-               $xmlString = ob_get_clean();
 
                // This throws error if invalid xml output
-               $xmlObject = simplexml_load_string( $xmlString );
+               $xmlObject = simplexml_load_string( $sink );
 
                /**
                 * Check namespaces match xml
index 9f2fdfe..1d48d08 100644 (file)
@@ -413,8 +413,8 @@ class GlobalTest extends MediaWikiTestCase {
                );
        }
 
-       /** array( shorthand, expected integer ) */
        public static function provideShorthand() {
+               // Syntax: [ shorthand, expected integer ]
                return [
                        # Null, empty ...
                        [ '', -1 ],
index 082fe22..c76666d 100644 (file)
@@ -97,7 +97,7 @@ class WfBCP47Test extends MediaWikiTestCase {
                         *  az-Arab-x-AZE-derbend
                         * AZE being private, it should be lower case, hence the test above
                         * should probably be:
-                        *  array( 'az-arab-x-aze-derbend', 'az-Arab-x-AZE-derbend' ),
+                        * [ 'az-arab-x-aze-derbend', 'az-Arab-x-AZE-derbend' ],
                         */
 
                        # Private use registry values:
index 1f1c9be..cbe2e2f 100644 (file)
@@ -80,12 +80,12 @@ class WfUrlencodeTest extends MediaWikiTestCase {
 
        /**
         * Format is either:
-        *   array( 'input', 'expected' );
+        *   [ 'input', 'expected' ];
         * Or:
-        *   array( 'input',
-        *       array( 'Apache', 'expected' ),
-        *       array( 'Microsoft-IIS/7', 'expected' ),
-        *    ),
+        *   [ 'input',
+        *       [ 'Apache', 'expected' ],
+        *       [ 'Microsoft-IIS/7', 'expected' ],
+        *   ],
         * If you want to add other HTTP server name, you will have to add a new
         * testing method much like the testEncodingUrlWith() method above.
         */
index 4721793..e44db83 100644 (file)
@@ -738,6 +738,16 @@ class HtmlTest extends MediaWikiTestCase {
                                '1x.png 1x, 1_5x.png 1.5x, 2x.png 2x',
                                'pixel depth keys may omit a trailing "x"'
                        ],
+                       [
+                               [ '1'  => 'small.png', '1.5' => 'large.png', '2'  => 'large.png' ],
+                               'small.png 1x, large.png 1.5x',
+                               'omit larger duplicates'
+                       ],
+                       [
+                               [ '1'  => 'small.png', '2'  => 'large.png', '1.5' => 'large.png' ],
+                               'small.png 1x, large.png 1.5x',
+                               'omit larger duplicates in irregular order'
+                       ],
                ];
        }
 
index 4c2e02b..ae0b4be 100644 (file)
@@ -106,8 +106,8 @@ class HttpTest extends MediaWikiTestCase {
                        # (\S+) - host part is made of anything not whitespaces
                        // commented these out in order to remove @group Broken
                        // @todo are these valid tests? if so, fix Http::isValidURI so it can handle them
-                       // array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ),
-                       // array( false, 'http://exam:ple.org/', 'hostname can not use colons!' ),
+                       // [ false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ],
+                       // [ false, 'http://exam:ple.org/', 'hostname can not use colons!' ],
 
                        # (:[0-9]+)? - port number
                        [ true, 'http://example.org:80/' ],
@@ -212,11 +212,11 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLAUTH_DIGEST' ],
                        [ 'CURLAUTH_GSSNEGOTIATE' ],
                        [ 'CURLAUTH_NTLM' ],
-                       // array( 'CURLCLOSEPOLICY_CALLBACK' ), // removed in PHP 5.6.0
-                       // array( 'CURLCLOSEPOLICY_LEAST_RECENTLY_USED' ), // removed in PHP 5.6.0
-                       // array( 'CURLCLOSEPOLICY_LEAST_TRAFFIC' ), // removed in PHP 5.6.0
-                       // array( 'CURLCLOSEPOLICY_OLDEST' ), // removed in PHP 5.6.0
-                       // array( 'CURLCLOSEPOLICY_SLOWEST' ), // removed in PHP 5.6.0
+                       // [ 'CURLCLOSEPOLICY_CALLBACK' ], // removed in PHP 5.6.0
+                       // [ 'CURLCLOSEPOLICY_LEAST_RECENTLY_USED' ], // removed in PHP 5.6.0
+                       // [ 'CURLCLOSEPOLICY_LEAST_TRAFFIC' ], // removed in PHP 5.6.0
+                       // [ 'CURLCLOSEPOLICY_OLDEST' ], // removed in PHP 5.6.0
+                       // [ 'CURLCLOSEPOLICY_SLOWEST' ], // removed in PHP 5.6.0
                        [ 'CURLE_ABORTED_BY_CALLBACK' ],
                        [ 'CURLE_BAD_CALLING_ORDER' ],
                        [ 'CURLE_BAD_CONTENT_ENCODING' ],
@@ -268,7 +268,7 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLE_RECV_ERROR' ],
                        [ 'CURLE_SEND_ERROR' ],
                        [ 'CURLE_SHARE_IN_USE' ],
-                       // array( 'CURLE_SSH' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLE_SSH' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLE_SSL_CACERT' ],
                        [ 'CURLE_SSL_CERTPROBLEM' ],
                        [ 'CURLE_SSL_CIPHER' ],
@@ -286,14 +286,14 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLFTPAUTH_DEFAULT' ],
                        [ 'CURLFTPAUTH_SSL' ],
                        [ 'CURLFTPAUTH_TLS' ],
-                       // array( 'CURLFTPMETHOD_MULTICWD' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLFTPMETHOD_NOCWD' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLFTPMETHOD_SINGLECWD' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLFTPMETHOD_MULTICWD' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLFTPMETHOD_NOCWD' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLFTPMETHOD_SINGLECWD' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLFTPSSL_ALL' ],
                        [ 'CURLFTPSSL_CONTROL' ],
                        [ 'CURLFTPSSL_NONE' ],
                        [ 'CURLFTPSSL_TRY' ],
-                       // array( 'CURLINFO_CERTINFO' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLINFO_CERTINFO' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLINFO_CONNECT_TIME' ],
                        [ 'CURLINFO_CONTENT_LENGTH_DOWNLOAD' ],
                        [ 'CURLINFO_CONTENT_LENGTH_UPLOAD' ],
@@ -308,7 +308,7 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLINFO_PRIVATE' ],
                        [ 'CURLINFO_REDIRECT_COUNT' ],
                        [ 'CURLINFO_REDIRECT_TIME' ],
-                       // array( 'CURLINFO_REDIRECT_URL' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLINFO_REDIRECT_URL' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLINFO_REQUEST_SIZE' ],
                        [ 'CURLINFO_SIZE_DOWNLOAD' ],
                        [ 'CURLINFO_SIZE_UPLOAD' ],
@@ -329,8 +329,8 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLOPT_BUFFERSIZE' ],
                        [ 'CURLOPT_CAINFO' ],
                        [ 'CURLOPT_CAPATH' ],
-                       // array( 'CURLOPT_CERTINFO' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLOPT_CLOSEPOLICY' ), // removed in PHP 5.6.0
+                       // [ 'CURLOPT_CERTINFO' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_CLOSEPOLICY' ], // removed in PHP 5.6.0
                        [ 'CURLOPT_CONNECTTIMEOUT' ],
                        [ 'CURLOPT_CONNECTTIMEOUT_MS' ],
                        [ 'CURLOPT_COOKIE' ],
@@ -354,8 +354,8 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLOPT_FTPPORT' ],
                        [ 'CURLOPT_FTPSSLAUTH' ],
                        [ 'CURLOPT_FTP_CREATE_MISSING_DIRS' ],
-                       // array( 'CURLOPT_FTP_FILEMETHOD' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLOPT_FTP_SKIP_PASV_IP' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_FTP_FILEMETHOD' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_FTP_SKIP_PASV_IP' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLOPT_FTP_SSL' ],
                        [ 'CURLOPT_FTP_USE_EPRT' ],
                        [ 'CURLOPT_FTP_USE_EPSV' ],
@@ -371,14 +371,14 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLOPT_INFILESIZE' ],
                        [ 'CURLOPT_INTERFACE' ],
                        [ 'CURLOPT_IPRESOLVE' ],
-                       // array( 'CURLOPT_KEYPASSWD' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_KEYPASSWD' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLOPT_KRB4LEVEL' ],
                        [ 'CURLOPT_LOW_SPEED_LIMIT' ],
                        [ 'CURLOPT_LOW_SPEED_TIME' ],
                        [ 'CURLOPT_MAXCONNECTS' ],
                        [ 'CURLOPT_MAXREDIRS' ],
-                       // array( 'CURLOPT_MAX_RECV_SPEED_LARGE' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLOPT_MAX_SEND_SPEED_LARGE' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_MAX_RECV_SPEED_LARGE' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_MAX_SEND_SPEED_LARGE' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLOPT_NETRC' ],
                        [ 'CURLOPT_NOBODY' ],
                        [ 'CURLOPT_NOPROGRESS' ],
@@ -390,7 +390,7 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLOPT_POSTREDIR' ],
                        [ 'CURLOPT_PRIVATE' ],
                        [ 'CURLOPT_PROGRESSFUNCTION' ],
-                       // array( 'CURLOPT_PROTOCOLS' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_PROTOCOLS' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLOPT_PROXY' ],
                        [ 'CURLOPT_PROXYAUTH' ],
                        [ 'CURLOPT_PROXYPORT' ],
@@ -402,14 +402,14 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLOPT_RANGE' ],
                        [ 'CURLOPT_READDATA' ],
                        [ 'CURLOPT_READFUNCTION' ],
-                       // array( 'CURLOPT_REDIR_PROTOCOLS' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_REDIR_PROTOCOLS' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLOPT_REFERER' ],
                        [ 'CURLOPT_RESUME_FROM' ],
                        [ 'CURLOPT_RETURNTRANSFER' ],
-                       // array( 'CURLOPT_SSH_AUTH_TYPES' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLOPT_SSH_HOST_PUBLIC_KEY_MD5' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLOPT_SSH_PRIVATE_KEYFILE' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLOPT_SSH_PUBLIC_KEYFILE' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_SSH_AUTH_TYPES' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_SSH_HOST_PUBLIC_KEY_MD5' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_SSH_PRIVATE_KEYFILE' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLOPT_SSH_PUBLIC_KEYFILE' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLOPT_SSLCERT' ],
                        [ 'CURLOPT_SSLCERTPASSWD' ],
                        [ 'CURLOPT_SSLCERTTYPE' ],
@@ -437,28 +437,28 @@ class HttpTest extends MediaWikiTestCase {
                        [ 'CURLOPT_VERBOSE' ],
                        [ 'CURLOPT_WRITEFUNCTION' ],
                        [ 'CURLOPT_WRITEHEADER' ],
-                       // array( 'CURLPROTO_ALL' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_DICT' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_FILE' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_FTP' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_FTPS' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_HTTP' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_HTTPS' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_LDAP' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_LDAPS' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_SCP' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_SFTP' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_TELNET' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLPROTO_TFTP' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_ALL' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_DICT' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_FILE' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_FTP' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_FTPS' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_HTTP' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_HTTPS' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_LDAP' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_LDAPS' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_SCP' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_SFTP' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_TELNET' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROTO_TFTP' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLPROXY_HTTP' ],
-                       // array( 'CURLPROXY_SOCKS4' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLPROXY_SOCKS4' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLPROXY_SOCKS5' ],
-                       // array( 'CURLSSH_AUTH_DEFAULT' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLSSH_AUTH_HOST' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLSSH_AUTH_KEYBOARD' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLSSH_AUTH_NONE' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLSSH_AUTH_PASSWORD' ), // not present in HHVM 3.3.0-dev
-                       // array( 'CURLSSH_AUTH_PUBLICKEY' ), // not present in HHVM 3.3.0-dev
+                       // [ 'CURLSSH_AUTH_DEFAULT' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLSSH_AUTH_HOST' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLSSH_AUTH_KEYBOARD' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLSSH_AUTH_NONE' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLSSH_AUTH_PASSWORD' ], // not present in HHVM 3.3.0-dev
+                       // [ 'CURLSSH_AUTH_PUBLICKEY' ], // not present in HHVM 3.3.0-dev
                        [ 'CURLVERSION_NOW' ],
                        [ 'CURL_HTTP_VERSION_1_0' ],
                        [ 'CURL_HTTP_VERSION_1_1' ],
index b7f7880..63753f9 100644 (file)
@@ -429,6 +429,7 @@ class LinkerTest extends MediaWikiLangTestCase {
         * @covers Linker::getLinkColour
         */
        public function testGetLinkColour() {
+               $this->hideDeprecated( 'Linker::getLinkColour' );
                $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $foobarTitle = Title::makeTitle( NS_MAIN, 'FooBar' );
                $redirectTitle = Title::makeTitle( NS_MAIN, 'Redirect' );
index ca01aef..24db445 100644 (file)
@@ -387,7 +387,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
                $wgContentNamespaces = 5;
                $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
 
-               # test $wgContentNamespaces === array()
+               # test $wgContentNamespaces === []
                $wgContentNamespaces = [];
                $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
 
@@ -474,7 +474,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
         * global $wgCapitalLink setting to have extended coverage.
         *
         * MWNamespace::isCapitalized() rely on two global settings:
-        *   $wgCapitalLinkOverrides = array(); by default
+        *   $wgCapitalLinkOverrides = []; by default
         *   $wgCapitalLinks = true; by default
         * This function test $wgCapitalLinks
         *
index bca3982..70e4aea 100644 (file)
@@ -102,7 +102,7 @@ class MWTimestampTest extends MediaWikiLangTestCase {
 
        /**
         * Returns a list of valid timestamps in the format:
-        * array( type, timestamp_of_type, timestamp_in_MW )
+        * [ type, timestamp_of_type, timestamp_in_MW ]
         */
        public static function provideValidTimestamps() {
                return [
@@ -124,7 +124,7 @@ class MWTimestampTest extends MediaWikiLangTestCase {
 
        /**
         * Returns a list of out of range timestamps in the format:
-        * array( type, timestamp_of_type )
+        * [ type, timestamp_of_type ]
         */
        public static function provideOutOfRangeTimestamps() {
                return [
index 3866190..7d3007b 100644 (file)
@@ -317,42 +317,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
        /**
         * @covers Revision::getContentModel
         */
-       public function testGetContentModel_default_model() {
-               global $wgContentHandlerUseDB;
-
-               if ( !$wgContentHandlerUseDB ) {
-                       $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
-               }
-
-               $orig = $this->makeRevision( [ 'text' => 'hello hello.', ] );
-
-               // Change namespace default content model, to make sure getContentModel() uses the
-               // page content model, not the namespace default.
-               $ns = $this->getDefaultWikitextNS();
-               $this->mergeMwGlobalArrayValue( 'wgNamespaceContentModels', [ $ns => CONTENT_MODEL_JSON ] );
-
-               $rev = Revision::newFromId( $orig->getId() );
-
-               // we should still get the correct content model from the page table
-               $this->assertEquals( CONTENT_MODEL_WIKITEXT, $rev->getContentModel() );
-
-               // check that we don't null the revision model if it's equal to the default, but not to
-               // the current page model.
-               $second = $this->makeRevision( [
-                       'text' => '{ "say":"hello" }',
-                       'content_model' => CONTENT_MODEL_JAVASCRIPT
-               ] );
-
-               $rev = Revision::newFromId( $second->getId() );
-
-               // we should now get the content model from the revision table
-               $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
-       }
-
-       /**
-        * @covers Revision::getContentModel
-        */
-       public function testGetContentModel_other_model() {
+       public function testGetContentModel() {
                global $wgContentHandlerUseDB;
 
                if ( !$wgContentHandlerUseDB ) {
@@ -360,7 +325,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                }
 
                $orig = $this->makeRevision( [ 'text' => 'hello hello.',
-                                                    'content_model' => CONTENT_MODEL_JAVASCRIPT ] );
+                       'content_model' => CONTENT_MODEL_JAVASCRIPT ] );
                $rev = Revision::newFromId( $orig->getId() );
 
                $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
index 72d7166..26529e8 100644 (file)
@@ -248,7 +248,7 @@ class SanitizerTest extends MediaWikiTestCase {
        }
 
        public static function provideDeprecatedAttributes() {
-               /** array( <attribute>, <element>, [message] ) */
+               /** [ <attribute>, <element>, [message] ] */
                return [
                        [ 'clear="left"', 'br' ],
                        [ 'clear="all"', 'br' ],
@@ -276,7 +276,7 @@ class SanitizerTest extends MediaWikiTestCase {
        }
 
        public static function provideCssCommentsFixtures() {
-               /** array( <expected>, <css>, [message] ) */
+               /** [ <expected>, <css>, [message] ] */
                return [
                        // Valid comments spanning entire input
                        [ '/**/', '/**/' ],
@@ -353,7 +353,7 @@ class SanitizerTest extends MediaWikiTestCase {
        }
 
        public static function provideEscapeIdReferenceList() {
-               /** array( <reference list>, <individual id 1>, <individual id 2> ) */
+               /** [ <reference list>, <individual id 1>, <individual id 2> ] */
                return [
                        [ 'foo bar', 'foo', 'bar' ],
                        [ '#1 #2', '#1', '#2' ],
index 2d2e726..030d9d5 100644 (file)
@@ -2444,10 +2444,10 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
        public function testUpdateNotificationTimestamp_watchersExist() {
                $mockDb = $this->getMockDb();
                $mockDb->expects( $this->once() )
-                       ->method( 'select' )
+                       ->method( 'selectFieldValues' )
                        ->with(
-                               [ 'watchlist' ],
-                               [ 'wl_user' ],
+                               'watchlist',
+                               'wl_user',
                                [
                                        'wl_user != 1',
                                        'wl_namespace' => 0,
@@ -2455,18 +2455,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                        'wl_notificationtimestamp IS NULL'
                                ]
                        )
-                       ->will(
-                               $this->returnValue( [
-                                       $this->getFakeRow( [ 'wl_user' => '2' ] ),
-                                       $this->getFakeRow( [ 'wl_user' => '3' ] )
-                               ] )
-                       );
-               $mockDb->expects( $this->once() )
-                       ->method( 'onTransactionIdle' )
-                       ->with( $this->isType( 'callable' ) )
-                       ->will( $this->returnCallback( function( $callable ) {
-                               $callable();
-                       } ) );
+                       ->will( $this->returnValue( [ '2', '3' ] ) );
                $mockDb->expects( $this->once() )
                        ->method( 'update' )
                        ->with(
@@ -2502,10 +2491,10 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
        public function testUpdateNotificationTimestamp_noWatchers() {
                $mockDb = $this->getMockDb();
                $mockDb->expects( $this->once() )
-                       ->method( 'select' )
+                       ->method( 'selectFieldValues' )
                        ->with(
-                               [ 'watchlist' ],
-                               [ 'wl_user' ],
+                               'watchlist',
+                               'wl_user',
                                [
                                        'wl_user != 1',
                                        'wl_namespace' => 0,
@@ -2516,8 +2505,6 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->will(
                                $this->returnValue( [] )
                        );
-               $mockDb->expects( $this->never() )
-                       ->method( 'onTransactionIdle' );
                $mockDb->expects( $this->never() )
                        ->method( 'update' );
 
@@ -2551,19 +2538,10 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                $this->getFakeRow( [ 'wl_notificationtimestamp' => '20151212010101' ] )
                        ) );
                $mockDb->expects( $this->once() )
-                       ->method( 'select' )
+                       ->method( 'selectFieldValues' )
                        ->will(
-                               $this->returnValue( [
-                                       $this->getFakeRow( [ 'wl_user' => '2' ] ),
-                                       $this->getFakeRow( [ 'wl_user' => '3' ] )
-                               ] )
+                               $this->returnValue( [ '2', '3' ] )
                        );
-               $mockDb->expects( $this->once() )
-                       ->method( 'onTransactionIdle' )
-                       ->with( $this->isType( 'callable' ) )
-                       ->will( $this->returnCallback( function( $callable ) {
-                               $callable();
-                       } ) );
                $mockDb->expects( $this->once() )
                        ->method( 'update' );
 
index 16f210b..ccabab6 100644 (file)
@@ -35,9 +35,7 @@ class RCCacheEntryFactoryTest extends MediaWikiLangTestCase {
                        'wgArticlePath' => '/wiki/$1'
                ] );
 
-               $this->linkRenderer = new LinkRenderer(
-                       MediaWikiServices::getInstance()->getTitleFormatter()
-               );
+               $this->linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
        }
 
        public function testNewFromRecentChange() {
index cac3d43..ae51a6c 100644 (file)
@@ -103,9 +103,7 @@ class TestRecentChangesHelper {
                $rcCacheFactory = new RCCacheEntryFactory(
                        new RequestContext(),
                        [ 'diff' => 'diff', 'cur' => 'cur', 'last' => 'last' ],
-                       new LinkRenderer(
-                               MediaWikiServices::getInstance()->getTitleFormatter()
-                       )
+                       MediaWikiServices::getInstance()->getLinkRenderer()
                );
                return $rcCacheFactory->newFromRecentChange( $recentChange, false );
        }
index a2aef35..d2078d7 100644 (file)
@@ -101,15 +101,15 @@ class CssContentTest extends JavaScriptContentTest {
         */
        public static function provideGetRedirectTarget() {
                // @codingStandardsIgnoreStart Generic.Files.LineLength
-               return array(
-                       array( 'MediaWiki:MonoBook.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=MediaWiki:MonoBook.css&action=raw&ctype=text/css);" ),
-                       array( 'User:FooBar/common.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=User:FooBar/common.css&action=raw&ctype=text/css);" ),
-                       array( 'Gadget:FooBaz.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ),
+               return [
+                       [ 'MediaWiki:MonoBook.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=MediaWiki:MonoBook.css&action=raw&ctype=text/css);" ],
+                       [ 'User:FooBar/common.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=User:FooBar/common.css&action=raw&ctype=text/css);" ],
+                       [ 'Gadget:FooBaz.css', "/* #REDIRECT */@import url(//example.org/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ],
                        # No #REDIRECT comment
-                       array( null, "@import url(//example.org/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ),
+                       [ null, "@import url(//example.org/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ],
                        # Wrong domain
-                       array( null, "/* #REDIRECT */@import url(//example.com/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ),
-               );
+                       [ null, "/* #REDIRECT */@import url(//example.com/w/index.php?title=Gadget:FooBaz.css&action=raw&ctype=text/css);" ],
+               ];
                // @codingStandardsIgnoreEnd
        }
 
index bb747c7..bb7eb79 100644 (file)
@@ -250,26 +250,71 @@ class DatabaseMysqlBaseTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideComparePositions
         */
-       function testHasReached( MySQLMasterPos $lowerPos, MySQLMasterPos $higherPos ) {
-               $this->assertTrue( $higherPos->hasReached( $lowerPos ) );
-               $this->assertTrue( $higherPos->hasReached( $higherPos ) );
-               $this->assertTrue( $lowerPos->hasReached( $lowerPos ) );
-               $this->assertFalse( $lowerPos->hasReached( $higherPos ) );
+       function testHasReached( MySQLMasterPos $lowerPos, MySQLMasterPos $higherPos, $match ) {
+               if ( $match ) {
+                       $this->assertTrue( $lowerPos->channelsMatch( $higherPos ) );
+
+                       $this->assertTrue( $higherPos->hasReached( $lowerPos ) );
+                       $this->assertTrue( $higherPos->hasReached( $higherPos ) );
+                       $this->assertTrue( $lowerPos->hasReached( $lowerPos ) );
+                       $this->assertFalse( $lowerPos->hasReached( $higherPos ) );
+               } else { // channels don't match
+                       $this->assertFalse( $lowerPos->channelsMatch( $higherPos ) );
+
+                       $this->assertFalse( $higherPos->hasReached( $lowerPos ) );
+                       $this->assertFalse( $lowerPos->hasReached( $higherPos ) );
+               }
        }
 
        function provideComparePositions() {
                return [
+                       // Binlog style
                        [
                                new MySQLMasterPos( 'db1034-bin.000976', '843431247' ),
-                               new MySQLMasterPos( 'db1034-bin.000976', '843431248' )
+                               new MySQLMasterPos( 'db1034-bin.000976', '843431248' ),
+                               true
                        ],
                        [
                                new MySQLMasterPos( 'db1034-bin.000976', '999' ),
-                               new MySQLMasterPos( 'db1034-bin.000976', '1000' )
+                               new MySQLMasterPos( 'db1034-bin.000976', '1000' ),
+                               true
                        ],
                        [
                                new MySQLMasterPos( 'db1034-bin.000976', '999' ),
-                               new MySQLMasterPos( 'db1035-bin.000976', '1000' )
+                               new MySQLMasterPos( 'db1035-bin.000976', '1000' ),
+                               false
+                       ],
+                       // MySQL GTID style
+                       [
+                               new MySQLMasterPos( 'db1-bin.2', '1', '3E11FA47-71CA-11E1-9E33-C80AA9429562:23' ),
+                               new MySQLMasterPos( 'db1-bin.2', '2', '3E11FA47-71CA-11E1-9E33-C80AA9429562:24' ),
+                               true
+                       ],
+                       [
+                               new MySQLMasterPos( 'db1-bin.2', '1', '3E11FA47-71CA-11E1-9E33-C80AA9429562:99' ),
+                               new MySQLMasterPos( 'db1-bin.2', '2', '3E11FA47-71CA-11E1-9E33-C80AA9429562:100' ),
+                               true
+                       ],
+                       [
+                               new MySQLMasterPos( 'db1-bin.2', '1', '3E11FA47-71CA-11E1-9E33-C80AA9429562:99' ),
+                               new MySQLMasterPos( 'db1-bin.2', '2', '1E11FA47-71CA-11E1-9E33-C80AA9429562:100' ),
+                               false
+                       ],
+                       // MariaDB GTID style
+                       [
+                               new MySQLMasterPos( 'db1-bin.2', '1', '255-11-23' ),
+                               new MySQLMasterPos( 'db1-bin.2', '2', '255-11-24' ),
+                               true
+                       ],
+                       [
+                               new MySQLMasterPos( 'db1-bin.2', '1', '255-11-99' ),
+                               new MySQLMasterPos( 'db1-bin.2', '2', '255-11-100' ),
+                               true
+                       ],
+                       [
+                               new MySQLMasterPos( 'db1-bin.2', '1', '255-11-999' ),
+                               new MySQLMasterPos( 'db1-bin.2', '2', '254-11-1000' ),
+                               false
                        ],
                ];
        }
index 4aeddc6..254cfbd 100644 (file)
@@ -1139,16 +1139,16 @@ class FileBackendTest extends MediaWikiTestCase {
                $this->tearDownFiles();
                $this->doTestStreamFile( $path, $content, $alreadyExists );
                $this->tearDownFiles();
+
+               $this->backend = $this->multiBackend;
+               $this->tearDownFiles();
+               $this->doTestStreamFile( $path, $content, $alreadyExists );
+               $this->tearDownFiles();
        }
 
        private function doTestStreamFile( $path, $content ) {
                $backendName = $this->backendClass();
 
-               // Test doStreamFile() directly to avoid header madness
-               $class = new ReflectionClass( $this->backend );
-               $method = $class->getMethod( 'doStreamFile' );
-               $method->setAccessible( true );
-
                if ( $content !== null ) {
                        $this->prepare( [ 'dir' => dirname( $path ) ] );
                        $status = $this->create( [ 'dst' => $path, 'content' => $content ] );
@@ -1156,18 +1156,19 @@ class FileBackendTest extends MediaWikiTestCase {
                                "Creation of file at $path succeeded ($backendName)." );
 
                        ob_start();
-                       $method->invokeArgs( $this->backend, [ [ 'src' => $path ] ] );
+                       $this->backend->streamFile( [ 'src' => $path, 'headless' => 1, 'allowOB' => 1 ] );
                        $data = ob_get_contents();
                        ob_end_clean();
 
                        $this->assertEquals( $content, $data, "Correct content streamed from '$path'" );
                } else { // 404 case
                        ob_start();
-                       $method->invokeArgs( $this->backend, [ [ 'src' => $path ] ] );
+                       $this->backend->streamFile( [ 'src' => $path, 'headless' => 1, 'allowOB' => 1 ] );
                        $data = ob_get_contents();
                        ob_end_clean();
 
-                       $this->assertEquals( '', $data, "Correct content streamed from '$path' ($backendName)" );
+                       $this->assertRegExp( '#<h1>File not found</h1>#', $data,
+                               "Correct content streamed from '$path' ($backendName)" );
                }
        }
 
@@ -1181,6 +1182,53 @@ class FileBackendTest extends MediaWikiTestCase {
                return $cases;
        }
 
+       public function testStreamFileRange() {
+               $this->backend = $this->singleBackend;
+               $this->tearDownFiles();
+               $this->doTestStreamFileRange();
+               $this->tearDownFiles();
+
+               $this->backend = $this->multiBackend;
+               $this->tearDownFiles();
+               $this->doTestStreamFileRange();
+               $this->tearDownFiles();
+       }
+
+       private function doTestStreamFileRange() {
+               $backendName = $this->backendClass();
+
+               $base = self::baseStorePath();
+               $path = "$base/unittest-cont1/e/b/z/range_file.txt";
+               $content = "0123456789ABCDEF";
+
+               $this->prepare( [ 'dir' => dirname( $path ) ] );
+               $status = $this->create( [ 'dst' => $path, 'content' => $content ] );
+               $this->assertGoodStatus( $status,
+                       "Creation of file at $path succeeded ($backendName)." );
+
+               static $ranges = [
+                       'bytes=0-0'   => '0',
+                       'bytes=0-3'   => '0123',
+                       'bytes=4-8'   => '45678',
+                       'bytes=15-15' => 'F',
+                       'bytes=14-15' => 'EF',
+                       'bytes=-5'    => 'BCDEF',
+                       'bytes=-1'    => 'F',
+                       'bytes=10-16' => 'ABCDEF',
+                       'bytes=10-99' => 'ABCDEF',
+               ];
+
+               foreach ( $ranges as $range => $chunk ) {
+                       ob_start();
+                       $this->backend->streamFile( [ 'src' => $path, 'headless' => 1, 'allowOB' => 1,
+                               'options' => [ 'range' => $range ] ] );
+                       $data = ob_get_contents();
+                       ob_end_clean();
+
+                       $this->assertEquals( $chunk, $data, "Correct chunk streamed from '$path' for '$range'" );
+               }
+       }
+
        /**
         * @dataProvider provider_testGetFileContents
         * @covers FileBackend::getFileContents
@@ -1516,7 +1564,7 @@ class FileBackendTest extends MediaWikiTestCase {
                        [ "$base/unittest-cont1/e/a/z/some_file1.txt", true ],
                        [ "$base/unittest-cont2/a/z/some_file2.txt", true ],
                        # Specific to FS backend with no basePath field set
-                       # array( "$base/unittest-cont3/a/z/some_file3.txt", false ),
+                       # [ "$base/unittest-cont3/a/z/some_file3.txt", false ],
                ];
        }
 
index 5e5e921..09d31fc 100644 (file)
@@ -124,7 +124,7 @@ class FakeDatabase extends DatabaseBase {
         *
         * Example:
         * $id = $dbw->nextSequenceValue( 'page_page_id_seq' );
-        * $dbw->insert( 'page', array( 'page_id' => $id ) );
+        * $dbw->insert( 'page', [ 'page_id' => $id ] );
         * $id = $dbw->insertId();
         *
         * @return int
index 80efcb3..7f9a772 100644 (file)
@@ -30,6 +30,32 @@ class XmlTypeCheckTest extends PHPUnit_Framework_TestCase {
                $this->assertFalse( $testXML->wellFormed );
        }
 
+       /**
+        * Verify we check for recursive entity DOS
+        *
+        * (If the DOS isn't properly handled, the test runner will probably go OOM...)
+        */
+       public function testRecursiveEntity() {
+               $xml = <<<'XML'
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE foo [
+       <!ENTITY test "&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;">
+       <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+       <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+       <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+       <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+       <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+       <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+       <!ENTITY g "-00000000000000000000000000000000000000000000000000000000000000000000000-">
+]>
+<foo>
+<bar>&test;</bar>
+</foo>
+XML;
+               $check = XmlTypeCheck::newFromString( $xml );
+               $this->assertFalse( $check->wellFormed );
+       }
+
        /**
         * @covers XMLTypeCheck::processingInstructionHandler
         */
index ed28b79..bf12f80 100644 (file)
@@ -14,9 +14,15 @@ class LinkRendererFactoryTest extends MediaWikiLangTestCase {
         */
        private $titleFormatter;
 
+       /**
+        * @var LinkCache
+        */
+       private $linkCache;
+
        public function setUp() {
                parent::setUp();
                $this->titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
+               $this->linkCache = MediaWikiServices::getInstance()->getLinkCache();
        }
 
        public static function provideCreateFromLegacyOptions() {
@@ -48,7 +54,7 @@ class LinkRendererFactoryTest extends MediaWikiLangTestCase {
         * @dataProvider provideCreateFromLegacyOptions
         */
        public function testCreateFromLegacyOptions( $options, $func, $val ) {
-               $factory = new LinkRendererFactory( $this->titleFormatter );
+               $factory = new LinkRendererFactory( $this->titleFormatter, $this->linkCache );
                $linkRenderer = $factory->createFromLegacyOptions(
                        $options
                );
@@ -57,16 +63,17 @@ class LinkRendererFactoryTest extends MediaWikiLangTestCase {
        }
 
        public function testCreate() {
-               $factory = new LinkRendererFactory( $this->titleFormatter );
+               $factory = new LinkRendererFactory( $this->titleFormatter, $this->linkCache );
                $this->assertInstanceOf( LinkRenderer::class, $factory->create() );
        }
 
        public function testCreateForUser() {
+               /** @var PHPUnit_Framework_MockObject_MockObject|User $user */
                $user = $this->getMock( User::class, [ 'getStubThreshold' ] );
                $user->expects( $this->once() )
                        ->method( 'getStubThreshold' )
                        ->willReturn( 15 );
-               $factory = new LinkRendererFactory( $this->titleFormatter );
+               $factory = new LinkRendererFactory( $this->titleFormatter, $this->linkCache );
                $linkRenderer = $factory->createForUser( $user );
                $this->assertInstanceOf( LinkRenderer::class, $linkRenderer );
                $this->assertEquals( 15, $linkRenderer->getStubThreshold() );
index b78592b..91789c5 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\Linker\LinkRenderer;
+use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -9,9 +10,9 @@ use MediaWiki\MediaWikiServices;
 class LinkRendererTest extends MediaWikiLangTestCase {
 
        /**
-        * @var TitleFormatter
+        * @var LinkRendererFactory
         */
-       private $titleFormatter;
+       private $factory;
 
        public function setUp() {
                parent::setUp();
@@ -22,12 +23,13 @@ class LinkRendererTest extends MediaWikiLangTestCase {
                        'wgScriptPath' => '/w',
                        'wgScript' => '/w/index.php',
                ] );
-               $this->titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
+               $this->factory = MediaWikiServices::getInstance()->getLinkRendererFactory();
+
        }
 
        public function testMergeAttribs() {
                $target = new TitleValue( NS_SPECIAL, 'Blankpage' );
-               $linkRenderer = new LinkRenderer( $this->titleFormatter );
+               $linkRenderer = $this->factory->create();
                $link = $linkRenderer->makeBrokenLink( $target, null, [
                        // Appended to class
                        'class' => 'foobar',
@@ -46,7 +48,7 @@ class LinkRendererTest extends MediaWikiLangTestCase {
 
        public function testMakeKnownLink() {
                $target = new TitleValue( NS_MAIN, 'Foobar' );
-               $linkRenderer = new LinkRenderer( $this->titleFormatter );
+               $linkRenderer = $this->factory->create();
 
                // Query added
                $this->assertEquals(
@@ -73,7 +75,7 @@ class LinkRendererTest extends MediaWikiLangTestCase {
        public function testMakeBrokenLink() {
                $target = new TitleValue( NS_MAIN, 'Foobar' );
                $special = new TitleValue( NS_SPECIAL, 'Foobar' );
-               $linkRenderer = new LinkRenderer( $this->titleFormatter );
+               $linkRenderer = $this->factory->create();
 
                // action=edit&redlink=1 added
                $this->assertEquals(
@@ -105,7 +107,7 @@ class LinkRendererTest extends MediaWikiLangTestCase {
        }
 
        public function testMakeLink() {
-               $linkRenderer = new LinkRenderer( $this->titleFormatter );
+               $linkRenderer = $this->factory->create();
                $foobar = new TitleValue( NS_SPECIAL, 'Foobar' );
                $blankpage = new TitleValue( NS_SPECIAL, 'Blankpage' );
                $this->assertEquals(
@@ -131,4 +133,57 @@ class LinkRendererTest extends MediaWikiLangTestCase {
                        $linkRenderer->makeLink( $foobar, new HtmlArmor( '<script>evil()</script>' ) )
                );
        }
+
+       public function testGetLinkClasses() {
+               $titleFormatter = MediaWikiServices::getInstance()->getTitleFormatter();
+               $linkCache = new LinkCache( $titleFormatter );
+               $foobarTitle = new TitleValue( NS_MAIN, 'FooBar' );
+               $redirectTitle = new TitleValue( NS_MAIN, 'Redirect' );
+               $userTitle = new TitleValue( NS_USER, 'Someuser' );
+               $linkCache->addGoodLinkObj(
+                       1, // id
+                       $foobarTitle,
+                       10, // len
+                       0 // redir
+               );
+               $linkCache->addGoodLinkObj(
+                       2, // id
+                       $redirectTitle,
+                       10, // len
+                       1 // redir
+               );
+
+               $linkCache->addGoodLinkObj(
+                       3, // id
+                       $userTitle,
+                       10, // len
+                       0 // redir
+               );
+
+               $linkRenderer = new LinkRenderer( $titleFormatter, $linkCache );
+               $linkRenderer->setStubThreshold( 0 );
+               $this->assertEquals(
+                       '',
+                       $linkRenderer->getLinkClasses( $foobarTitle )
+               );
+
+               $linkRenderer->setStubThreshold( 20 );
+               $this->assertEquals(
+                       'stub',
+                       $linkRenderer->getLinkClasses( $foobarTitle )
+               );
+
+               $linkRenderer->setStubThreshold( 0 );
+               $this->assertEquals(
+                       'mw-redirect',
+                       $linkRenderer->getLinkClasses( $redirectTitle )
+               );
+
+               $linkRenderer->setStubThreshold( 20 );
+               $this->assertEquals(
+                       '',
+                       $linkRenderer->getLinkClasses( $userTitle )
+               );
+       }
+
 }
index 8512572..c56626f 100644 (file)
@@ -163,12 +163,8 @@ class NewParserTest extends MediaWikiTestCase {
                $this->djVuSupport = new DjVuSupport();
                // Tidy support
                $this->tidySupport = new TidySupport();
-               $tmpGlobals['wgTidyConfig'] = null;
+               $tmpGlobals['wgTidyConfig'] = $this->tidySupport->getConfig();
                $tmpGlobals['wgUseTidy'] = false;
-               $tmpGlobals['wgDebugTidy'] = false;
-               $tmpGlobals['wgTidyConf'] = $IP . '/includes/tidy/tidy.conf';
-               $tmpGlobals['wgTidyOpts'] = '';
-               $tmpGlobals['wgTidyInternal'] = $this->tidySupport->isInternal();
 
                $this->setMwGlobals( $tmpGlobals );
 
@@ -452,7 +448,8 @@ class NewParserTest extends MediaWikiTestCase {
                        'wgMathDirectory' => $uploadDir . '/math',
                        'wgDefaultLanguageVariant' => $variant,
                        'wgLinkHolderBatchSize' => $linkHolderBatchSize,
-                       'wgUseTidy' => isset( $opts['tidy'] ),
+                       'wgUseTidy' => false,
+                       'wgTidyConfig' => isset( $opts['tidy'] ) ? $this->tidySupport->getConfig() : null
                ];
 
                if ( $config ) {
index 4aa4f41..1dfcd82 100644 (file)
@@ -14,7 +14,7 @@ class CoreVersionCheckerTest extends PHPUnit_Framework_TestCase {
 
        public static function provideCheck() {
                return [
-                       // array( $wgVersion, constraint, expected )
+                       // [ $wgVersion, constraint, expected ]
                        [ '1.25alpha', '>= 1.26', false ],
                        [ '1.25.0', '>= 1.26', false ],
                        [ '1.26alpha', '>= 1.26', true ],
index 0120d79..be7fe91 100644 (file)
@@ -108,7 +108,7 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers ExtensionProcessor::extractConfig
+        * @covers ExtensionProcessor::extractConfig1
         */
        public function testExtractConfig() {
                $processor = new ExtensionProcessor;
@@ -414,6 +414,26 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
                        ]
                ];
        }
+
+       public function testGlobalSettingsDocumentedInSchema() {
+               global $IP;
+               $globalSettings = TestingAccessWrapper::newFromClass(
+                       ExtensionProcessor::class )->globalSettings;
+
+               $schema = FormatJson::decode(
+                       file_get_contents( "$IP/docs/extension.schema.json" ),
+                       true
+               );
+               $missing = [];
+               foreach ( $globalSettings as $global ) {
+                       if ( !isset( $schema['properties'][$global] ) ) {
+                               $missing[] = $global;
+                       }
+               }
+
+               $this->assertEquals( [], $missing,
+                       "The following global settings are not documented in docs/extension.schema.json" );
+       }
 }
 
 /**
index ea775ae..9b62b82 100644 (file)
@@ -5,7 +5,7 @@ class ResourceLoaderStartUpModuleTest extends ResourceLoaderTestCase {
        // Version hash for a blank file module.
        // Result of ResourceLoader::makeHash(), ResourceLoaderTestModule
        // and ResourceLoaderFileModule::getDefinitionSummary().
-       protected static $blankVersion = '0a56zyi';
+       protected static $blankVersion = '09p30q0';
 
        protected static function expandPlaceholders( $text ) {
                return strtr( $text, [
index 4ea9686..3fa8a9f 100644 (file)
@@ -29,10 +29,10 @@ class SpecialSearchTest extends MediaWikiTestCase {
                        $this->newUserWithSearchNS( $userOptions )
                );
                /*
-               $context->setRequest( new FauxRequest( array(
+               $context->setRequest( new FauxRequest( [
                        'ns5'=>true,
                        'ns6'=>true,
-               ) ));
+               ] ));
                 */
                $context->setRequest( new FauxRequest( $requested ) );
                $search = new SpecialSearch();
diff --git a/tests/phpunit/includes/tidy/BalancerTest.php b/tests/phpunit/includes/tidy/BalancerTest.php
new file mode 100644 (file)
index 0000000..f69ecaf
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+
+class BalancerTest extends MediaWikiTestCase {
+       private $balancer;
+
+       /**
+        * Anything that needs to happen before your tests should go here.
+        */
+       protected function setUp() {
+               // Be sure to do call the parent setup and teardown functions.
+               // This makes sure that all the various cleanup and restorations
+               // happen as they should (including the restoration for setMwGlobals).
+               parent::setUp();
+               $this->balancer = new MediaWiki\Tidy\Balancer( [
+                       'strict' => false, /* not strict */
+                       'allowedHtmlElements' => null, /* no sanitization */
+                       'tidyCompat' => false, /* standard parser */
+                       'allowComments' => true, /* comment parsing */
+               ] );
+       }
+
+       /**
+        * @covers MediaWiki\Tidy\Balancer::balance
+        * @dataProvider provideBalancerTests
+        */
+       public function testBalancer( $description, $input, $expected ) {
+               $output = $this->balancer->balance( $input );
+
+               // Ignore self-closing tags
+               $output = preg_replace( '/\s*\/>/', '>', $output );
+
+               $this->assertEquals( $expected, $output, $description );
+       }
+
+       public static function provideBalancerTests() {
+               // Get the tests from html5lib-tests.json
+               $json = json_decode( file_get_contents(
+                       __DIR__ . '/html5lib-tests.json'
+               ), true );
+               // Munge this slightly into the format phpunit expects
+               // for providers, and filter out HTML constructs which
+               // the balancer doesn't support.
+               $tests = [];
+               $okre = "~ \A
+                       (?i:<!DOCTYPE\ html>)?
+                       <html><head></head><body>
+                       .*
+                       </body></html>
+               \z ~xs";
+               foreach ( $json as $filename => $cases ) {
+                       foreach ( $cases as $case ) {
+                               $html = $case['document']['html'];
+                               if ( !preg_match( $okre, $html ) ) {
+                                       // Skip tests which involve stuff in the <head> or
+                                       // weird doctypes.
+                                       continue;
+                               }
+                               // We used to do this:
+                               //   $html = substr( $html, strlen( $start ), -strlen( $end ) );
+                               // But now we use a different field in the test case,
+                               // which reports how domino would parse this case in a
+                               // no-quirks <body> context.  (The original test case may
+                               // have had a different context, or relied on quirks mode.)
+                               $html = $case['document']['noQuirksBodyHtml'];
+                               // Normalize case of SVG attributes.
+                               $html = str_replace( 'foreignObject', 'foreignobject', $html );
+                               // Normalize case of MathML attributes.
+                               $html = str_replace( 'definitionURL', 'definitionurl', $html );
+
+                               if (
+                                       isset( $case['document']['props']['comment'] ) &&
+                                       preg_match( ',<!--[^>]*<,', $html )
+                               ) {
+                                       // Skip tests which include HTML comments containing
+                                       // the < character, which we don't support.
+                                       continue;
+                               }
+                               if ( strpos( $case['data'], '<![CDATA[' ) !== false ) {
+                                       // Skip tests involving <![CDATA[ ]]> quoting.
+                                       continue;
+                               }
+                               if (
+                                       stripos( $case['data'], '<!DOCTYPE' ) !== false &&
+                                       stripos( $case['data'], '<!DOCTYPE html>' ) === false
+                               ) {
+                                       // Skip tests involving unusual doctypes.
+                                       continue;
+                               }
+                               $literalre = "~ <rdar: | <isindex | < /? (
+                                       html | head | body | frame | frameset | plaintext
+                               ) > ~xi";
+                               if ( preg_match( $literalre, $case['data'] ) ) {
+                                       // Skip tests involving some literal tags, which are
+                                       // unsupported but don't show up in the expected output.
+                                       continue;
+                               }
+                               if (
+                                       isset( $case['document']['props']['tags']['iframe'] ) ||
+                                       isset( $case['document']['props']['tags']['noembed'] ) ||
+                                       isset( $case['document']['props']['tags']['noscript'] ) ||
+                                       isset( $case['document']['props']['tags']['script'] ) ||
+                                       isset( $case['document']['props']['tags']['svg script'] ) ||
+                                       isset( $case['document']['props']['tags']['svg title'] ) ||
+                                       isset( $case['document']['props']['tags']['title'] ) ||
+                                       isset( $case['document']['props']['tags']['xmp'] )
+                               ) {
+                                       // Skip tests with unsupported tags which *do* show
+                                       // up in the expected output.
+                                       continue;
+                               }
+                               if (
+                                       $filename === 'entities01.dat' ||
+                                       $filename === 'entities02.dat' ||
+                                       preg_match( '/&([a-z]+|#x[0-9A-F]+);/i', $case['data'] ) ||
+                                       preg_match( '/^(&|&#|&#X|&#x|&#45|&x-test|&AMP)$/', $case['data'] )
+                               ) {
+                                       // Skip tests involving entity encoding.
+                                       continue;
+                               }
+                               if (
+                                       isset( $case['document']['props']['tagWithLt'] ) ||
+                                       isset( $case['document']['props']['attrWithFunnyChar'] ) ||
+                                       preg_match( ':^(</b test|<di|<foo bar=qux/>)$:', $case['data'] ) ||
+                                       preg_match( ':</p<p>:', $case['data'] ) ||
+                                       preg_match( ':<b &=&amp>|<p/x/y/z>:', $case['data'] )
+                               ) {
+                                       // Skip tests with funny tag or attribute names,
+                                       // which are really tests of the HTML tokenizer, not
+                                       // the tree builder.
+                                       continue;
+                               }
+                               if (
+                                       preg_match( ':encoding=" text/html "|type=" hidden":', $case['data'] )
+                               ) {
+                                       // The Sanitizer normalizes whitespace in attribute
+                                       // values, which makes this test case invalid.
+                                       continue;
+                               }
+                               if ( $filename === 'plain-text-unsafe.dat' ) {
+                                       // Skip tests with ASCII null, etc.
+                                       continue;
+                               }
+                               $data = preg_replace(
+                                       '~<!DOCTYPE html>~i', '', $case['data']
+                               );
+                               $tests[] = [
+                                       $filename, # use better description?
+                                       $data,
+                                       $html
+                               ];
+                       }
+               }
+               return $tests;
+       }
+}
diff --git a/tests/phpunit/includes/tidy/html5lib-tests.json b/tests/phpunit/includes/tidy/html5lib-tests.json
new file mode 100644 (file)
index 0000000..beb3659
--- /dev/null
@@ -0,0 +1,78905 @@
+{
+  "adoption01.dat": [
+    {
+      "data": "<a><p></a></p>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,10): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a></a><p><a></a></p></body></html>",
+        "noQuirksBodyHtml": "<a></a><p><a></a></p>"
+      }
+    },
+    {
+      "data": "<a>1<p>2</a>3</p>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,12): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "1"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "3"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a>1</a><p><a>2</a>3</p></body></html>",
+        "noQuirksBodyHtml": "<a>1</a><p><a>2</a>3</p>"
+      }
+    },
+    {
+      "data": "<a>1<button>2</a>3</button>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,17): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "button": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "1"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "button",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "3"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a>1</a><button><a>2</a>3</button></body></html>",
+        "noQuirksBodyHtml": "<a>1</a><button><a>2</a>3</button>"
+      }
+    },
+    {
+      "data": "<a>1<b>2</a>3</b>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,12): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "1"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "3"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a>1<b>2</b></a><b>3</b></body></html>",
+        "noQuirksBodyHtml": "<a>1<b>2</b></a><b>3</b>"
+      }
+    },
+    {
+      "data": "<a>1<div>2<div>3</a>4</div>5</div>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,20): adoption-agency-1.3",
+        "(1,20): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "1"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "a",
+                            "children": [
+                              {
+                                "text": "3"
+                              }
+                            ]
+                          },
+                          {
+                            "text": "4"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "5"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a>1</a><div><a>2</a><div><a>3</a>4</div>5</div></body></html>",
+        "noQuirksBodyHtml": "<a>1</a><div><a>2</a><div><a>3</a>4</div>5</div>"
+      }
+    },
+    {
+      "data": "<table><a>1<p>2</a>3</p>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,10): unexpected-start-tag-implies-table-voodoo",
+        "(1,11): unexpected-character-implies-table-voodoo",
+        "(1,14): unexpected-start-tag-implies-table-voodoo",
+        "(1,15): unexpected-character-implies-table-voodoo",
+        "(1,19): unexpected-end-tag-implies-table-voodoo",
+        "(1,19): adoption-agency-1.3",
+        "(1,20): unexpected-character-implies-table-voodoo",
+        "(1,24): unexpected-end-tag-implies-table-voodoo",
+        "(1,24): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "p": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "1"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "3"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a>1</a><p><a>2</a>3</p><table></table></body></html>",
+        "noQuirksBodyHtml": "<a>1</a><p><a>2</a>3</p><table></table>"
+      }
+    },
+    {
+      "data": "<b><b><a><p></a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,16): adoption-agency-1.3",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "a": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "a"
+                          },
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "tag": "a"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><b><a></a><p><a></a></p></b></b></body></html>",
+        "noQuirksBodyHtml": "<b><b><a></a><p><a></a></p></b></b>"
+      }
+    },
+    {
+      "data": "<b><a><b><p></a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,16): adoption-agency-1.3",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "a": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "tag": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "tag": "a"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><a><b></b></a><b><p><a></a></p></b></b></body></html>",
+        "noQuirksBodyHtml": "<b><a><b></b></a><b><p><a></a></p></b></b>"
+      }
+    },
+    {
+      "data": "<a><b><b><p></a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,16): adoption-agency-1.3",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "tag": "a"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><b><b></b></b></a><b><b><p><a></a></p></b></b></body></html>",
+        "noQuirksBodyHtml": "<a><b><b></b></b></a><b><b><p><a></a></p></b></b>"
+      }
+    },
+    {
+      "data": "<p>1<s id=\"A\">2<b id=\"B\">3</p>4</s>5</b>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,30): unexpected-end-tag",
+        "(1,35): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "s": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "1"
+                      },
+                      {
+                        "tag": "s",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "A"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "text": "2"
+                          },
+                          {
+                            "tag": "b",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "B"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "text": "3"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "s",
+                    "attrs": [
+                      {
+                        "name": "id",
+                        "value": "A"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "b",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "B"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "text": "4"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "attrs": [
+                      {
+                        "name": "id",
+                        "value": "B"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "5"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p>1<s id=\"A\">2<b id=\"B\">3</b></s></p><s id=\"A\"><b id=\"B\">4</b></s><b id=\"B\">5</b></body></html>",
+        "noQuirksBodyHtml": "<p>1<s id=\"A\">2<b id=\"B\">3</b></s></p><s id=\"A\"><b id=\"B\">4</b></s><b id=\"B\">5</b>"
+      }
+    },
+    {
+      "data": "<table><a>1<td>2</td>3</table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,10): unexpected-start-tag-implies-table-voodoo",
+        "(1,11): unexpected-character-implies-table-voodoo",
+        "(1,15): unexpected-cell-in-table-body",
+        "(1,30): unexpected-implied-end-tag-in-table-view"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "1"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "3"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "2"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a>1</a><a>3</a><table><tbody><tr><td>2</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<a>1</a><a>3</a><table><tbody><tr><td>2</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table>A<td>B</td>C</table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,8): unexpected-character-implies-table-voodoo",
+        "(1,12): unexpected-cell-in-table-body",
+        "(1,22): unexpected-character-implies-table-voodoo"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "AC"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "B"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>AC<table><tbody><tr><td>B</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "AC<table><tbody><tr><td>B</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<a><svg><tr><input></a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,23): unexpected-end-tag",
+        "(1,23): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "svg svg": true,
+            "svg tr": true,
+            "svg input": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "input",
+                                "ns": "http://www.w3.org/2000/svg"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><svg><tr><input></input></tr></svg></a></body></html>",
+        "noQuirksBodyHtml": "<a><svg><tr><input></input></tr></svg></a>"
+      }
+    },
+    {
+      "data": "<div><a><b><div><div><div><div><div><div><div><div><div><div></a>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,65): adoption-agency-1.3",
+        "(1,65): adoption-agency-1.3",
+        "(1,65): adoption-agency-1.3",
+        "(1,65): adoption-agency-1.3",
+        "(1,65): adoption-agency-1.3",
+        "(1,65): adoption-agency-1.3",
+        "(1,65): adoption-agency-1.3",
+        "(1,65): adoption-agency-1.3",
+        "(1,65): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "a": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "tag": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "tag": "a"
+                              },
+                              {
+                                "tag": "div",
+                                "children": [
+                                  {
+                                    "tag": "a"
+                                  },
+                                  {
+                                    "tag": "div",
+                                    "children": [
+                                      {
+                                        "tag": "a"
+                                      },
+                                      {
+                                        "tag": "div",
+                                        "children": [
+                                          {
+                                            "tag": "a"
+                                          },
+                                          {
+                                            "tag": "div",
+                                            "children": [
+                                              {
+                                                "tag": "a"
+                                              },
+                                              {
+                                                "tag": "div",
+                                                "children": [
+                                                  {
+                                                    "tag": "a"
+                                                  },
+                                                  {
+                                                    "tag": "div",
+                                                    "children": [
+                                                      {
+                                                        "tag": "a"
+                                                      },
+                                                      {
+                                                        "tag": "div",
+                                                        "children": [
+                                                          {
+                                                            "tag": "a",
+                                                            "children": [
+                                                              {
+                                                                "tag": "div",
+                                                                "children": [
+                                                                  {
+                                                                    "tag": "div"
+                                                                  }
+                                                                ]
+                                                              }
+                                                            ]
+                                                          }
+                                                        ]
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><a><b></b></a><b><div><a></a><div><a></a><div><a></a><div><a></a><div><a></a><div><a></a><div><a></a><div><a><div><div></div></div></a></div></div></div></div></div></div></div></div></b></div></body></html>",
+        "noQuirksBodyHtml": "<div><a><b></b></a><b><div><a></a><div><a></a><div><a></a><div><a></a><div><a></a><div><a></a><div><a></a><div><a><div><div></div></div></a></div></div></div></div></div></div></div></div></b></div>"
+      }
+    },
+    {
+      "data": "<div><a><b><u><i><code><div></a>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,32): adoption-agency-1.3",
+        "(1,32): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "a": true,
+            "b": true,
+            "u": true,
+            "i": true,
+            "code": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "tag": "u",
+                                "children": [
+                                  {
+                                    "tag": "i",
+                                    "children": [
+                                      {
+                                        "tag": "code"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "u",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "code",
+                                "children": [
+                                  {
+                                    "tag": "div",
+                                    "children": [
+                                      {
+                                        "tag": "a"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><a><b><u><i><code></code></i></u></b></a><u><i><code><div><a></a></div></code></i></u></div></body></html>",
+        "noQuirksBodyHtml": "<div><a><b><u><i><code></code></i></u></b></a><u><i><code><div><a></a></div></code></i></u></div>"
+      }
+    },
+    {
+      "data": "<b><b><b><b>x</b></b></b></b>y",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "text": "x"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "y"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><b><b><b>x</b></b></b></b>y</body></html>",
+        "noQuirksBodyHtml": "<b><b><b><b>x</b></b></b></b>y"
+      }
+    },
+    {
+      "data": "<p><b><b><b><b><p>x",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,18): unexpected-end-tag",
+        "(1,19): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "tag": "b"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "text": "x"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><b><b><b><b></b></b></b></b></p><p><b><b><b>x</b></b></b></p></body></html>",
+        "noQuirksBodyHtml": "<p><b><b><b><b></b></b></b></b></p><p><b><b><b>x</b></b></b></p>"
+      }
+    }
+  ],
+  "adoption02.dat": [
+    {
+      "data": "<b>1<i>2<p>3</b>4",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,16): adoption-agency-1.3",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "1"
+                      },
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "text": "3"
+                              }
+                            ]
+                          },
+                          {
+                            "text": "4"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b>1<i>2</i></b><i><p><b>3</b>4</p></i></body></html>",
+        "noQuirksBodyHtml": "<b>1<i>2</i></b><i><p><b>3</b>4</p></i>"
+      }
+    },
+    {
+      "data": "<a><div><style></style><address><a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,35): unexpected-start-tag-implies-end-tag",
+        "(1,35): adoption-agency-1.3",
+        "(1,35): adoption-agency-1.3",
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "div": true,
+            "style": true,
+            "address": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a"
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "tag": "style"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "address",
+                        "children": [
+                          {
+                            "tag": "a"
+                          },
+                          {
+                            "tag": "a"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a></a><div><a><style></style></a><address><a></a><a></a></address></div></body></html>",
+        "noQuirksBodyHtml": "<a></a><div><a><style></style></a><address><a></a><a></a></address></div>"
+      }
+    }
+  ],
+  "comments01.dat": [
+    {
+      "data": "FOO<!-- BAR -->BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": " BAR "
+                  },
+                  {
+                    "text": "BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!-- BAR -->BAZ</body></html>",
+        "noQuirksBodyHtml": "FOO<!-- BAR -->BAZ"
+      }
+    },
+    {
+      "data": "FOO<!-- BAR --!>BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,15): unexpected-bang-after-double-dash-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": " BAR "
+                  },
+                  {
+                    "text": "BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!-- BAR -->BAZ</body></html>",
+        "noQuirksBodyHtml": "FOO<!-- BAR -->BAZ"
+      }
+    },
+    {
+      "data": "FOO<!-- BAR --   >BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,15): unexpected-char-in-comment",
+        "(1,21): eof-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": " BAR --   >BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!-- BAR --   >BAZ--></body></html>",
+        "noQuirksBodyHtml": "FOO<!-- BAR --   >BAZ-->"
+      }
+    },
+    {
+      "data": "FOO<!-- BAR -- <QUX> -- MUX -->BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,15): unexpected-char-in-comment",
+        "(1,24): unexpected-char-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": " BAR -- <QUX> -- MUX "
+                  },
+                  {
+                    "text": "BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!-- BAR -- <QUX> -- MUX -->BAZ</body></html>",
+        "noQuirksBodyHtml": "FOO<!-- BAR -- <QUX> -- MUX -->BAZ"
+      }
+    },
+    {
+      "data": "FOO<!-- BAR -- <QUX> -- MUX --!>BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,15): unexpected-char-in-comment",
+        "(1,24): unexpected-char-in-comment",
+        "(1,31): unexpected-bang-after-double-dash-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": " BAR -- <QUX> -- MUX "
+                  },
+                  {
+                    "text": "BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!-- BAR -- <QUX> -- MUX -->BAZ</body></html>",
+        "noQuirksBodyHtml": "FOO<!-- BAR -- <QUX> -- MUX -->BAZ"
+      }
+    },
+    {
+      "data": "FOO<!-- BAR -- <QUX> -- MUX -- >BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,15): unexpected-char-in-comment",
+        "(1,24): unexpected-char-in-comment",
+        "(1,31): unexpected-char-in-comment",
+        "(1,35): eof-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": " BAR -- <QUX> -- MUX -- >BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!-- BAR -- <QUX> -- MUX -- >BAZ--></body></html>",
+        "noQuirksBodyHtml": "FOO<!-- BAR -- <QUX> -- MUX -- >BAZ-->"
+      }
+    },
+    {
+      "data": "FOO<!---->BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": ""
+                  },
+                  {
+                    "text": "BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!---->BAZ</body></html>",
+        "noQuirksBodyHtml": "FOO<!---->BAZ"
+      }
+    },
+    {
+      "data": "FOO<!--->BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,9): incorrect-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": ""
+                  },
+                  {
+                    "text": "BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!---->BAZ</body></html>",
+        "noQuirksBodyHtml": "FOO<!---->BAZ"
+      }
+    },
+    {
+      "data": "FOO<!-->BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,8): incorrect-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": ""
+                  },
+                  {
+                    "text": "BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!---->BAZ</body></html>",
+        "noQuirksBodyHtml": "FOO<!---->BAZ"
+      }
+    },
+    {
+      "data": "<?xml version=\"1.0\">Hi",
+      "errors": [
+        "(1,1): expected-tag-name-but-got-question-mark",
+        "(1,22): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "?xml version=\"1.0\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hi"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!--?xml version=\"1.0\"--><html><head></head><body>Hi</body></html>",
+        "noQuirksBodyHtml": "<!--?xml version=\"1.0\"-->Hi"
+      }
+    },
+    {
+      "data": "<?xml version=\"1.0\">",
+      "errors": [
+        "(1,1): expected-tag-name-but-got-question-mark",
+        "(1,20): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "?xml version=\"1.0\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--?xml version=\"1.0\"--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--?xml version=\"1.0\"-->"
+      }
+    },
+    {
+      "data": "<?xml version",
+      "errors": [
+        "(1,1): expected-tag-name-but-got-question-mark",
+        "(1,13): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "?xml version"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--?xml version--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--?xml version-->"
+      }
+    },
+    {
+      "data": "FOO<!----->BAZ",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,10): unexpected-dash-after-double-dash-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "comment": "-"
+                  },
+                  {
+                    "text": "BAZ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<!----->BAZ</body></html>",
+        "noQuirksBodyHtml": "FOO<!----->BAZ"
+      }
+    },
+    {
+      "data": "<html><!-- comment --><title>Comment before head</title>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "comment": " comment "
+              },
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "Comment before head"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><!-- comment --><head><title>Comment before head</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<!-- comment --><title>Comment before head</title>"
+      }
+    }
+  ],
+  "doctype01.dat": [
+    {
+      "data": "<!DOCTYPE html>Hello",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!dOctYpE HtMl>Hello",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPEhtml>Hello",
+      "errors": [
+        "(1,9): need-space-after-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE>Hello",
+      "errors": [
+        "(1,9): need-space-after-doctype",
+        "(1,10): expected-doctype-name-but-got-right-bracket",
+        "(1,10): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": ""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE ><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE >Hello",
+      "errors": [
+        "(1,11): expected-doctype-name-but-got-right-bracket",
+        "(1,11): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": ""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE ><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato>Hello",
+      "errors": [
+        "(1,17): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato >Hello",
+      "errors": [
+        "(1,18): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato taco>Hello",
+      "errors": [
+        "(1,17): expected-space-or-right-bracket-in-doctype",
+        "(1,22): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato taco \"ddd>Hello",
+      "errors": [
+        "(1,17): expected-space-or-right-bracket-in-doctype",
+        "(1,27): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato sYstEM>Hello",
+      "errors": [
+        "(1,24): unexpected-char-in-doctype",
+        "(1,24): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato sYstEM    >Hello",
+      "errors": [
+        "(1,28): unexpected-char-in-doctype",
+        "(1,28): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE   potato       sYstEM  ggg>Hello",
+      "errors": [
+        "(1,34): unexpected-char-in-doctype",
+        "(1,37): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato SYSTEM taco  >Hello",
+      "errors": [
+        "(1,25): unexpected-char-in-doctype",
+        "(1,31): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato SYSTEM 'taco\"'>Hello",
+      "errors": [
+        "(1,32): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato \"\" \"taco\"\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato SYSTEM \"taco\">Hello",
+      "errors": [
+        "(1,31): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato \"\" \"taco\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato SYSTEM \"tai'co\">Hello",
+      "errors": [
+        "(1,33): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato \"\" \"tai'co\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato SYSTEMtaco \"ddd\">Hello",
+      "errors": [
+        "(1,24): unexpected-char-in-doctype",
+        "(1,34): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato grass SYSTEM taco>Hello",
+      "errors": [
+        "(1,17): expected-space-or-right-bracket-in-doctype",
+        "(1,35): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato pUbLIc>Hello",
+      "errors": [
+        "(1,24): unexpected-end-of-doctype",
+        "(1,24): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato pUbLIc >Hello",
+      "errors": [
+        "(1,25): unexpected-end-of-doctype",
+        "(1,25): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato pUbLIcgoof>Hello",
+      "errors": [
+        "(1,24): unexpected-char-in-doctype",
+        "(1,28): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato PUBLIC goof>Hello",
+      "errors": [
+        "(1,25): unexpected-char-in-doctype",
+        "(1,29): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato PUBLIC \"go'of\">Hello",
+      "errors": [
+        "(1,32): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato \"go'of\" \"\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato PUBLIC 'go'of'>Hello",
+      "errors": [
+        "(1,29): unexpected-char-in-doctype",
+        "(1,32): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato \"go\" \"\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato PUBLIC 'go:hh   of' >Hello",
+      "errors": [
+        "(1,38): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato \"go:hh   of\" \"\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE potato PUBLIC \"W3C-//dfdf\" SYSTEM ggg>Hello",
+      "errors": [
+        "(1,38): unexpected-char-in-doctype",
+        "(1,48): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "potato \"W3C-//dfdf\" \"\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE potato><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n   \"http://www.w3.org/TR/html4/strict.dtd\">Hello",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE ...>Hello",
+      "errors": [
+        "(1,14): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "..."
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Hello"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE ...><html><head></head><body>Hello</body></html>",
+        "noQuirksBodyHtml": "Hello"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
+      "errors": [
+        "(2,58): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">",
+      "errors": [
+        "(2,54): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE root-element [SYSTEM OR PUBLIC FPI] \"uri\" [ \n<!-- internal declarations -->\n]>",
+      "errors": [
+        "(1,23): expected-space-or-right-bracket-in-doctype",
+        "(2,30): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "root-element"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "]>",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE root-element><html><head></head><body>]&gt;</body></html>",
+        "noQuirksBodyHtml": "\n]&gt;"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html PUBLIC\n  \"-//WAPFORUM//DTD XHTML Mobile 1.0//EN\"\n    \"http://www.wapforum.org/DTD/xhtml-mobile10.dtd\">",
+      "errors": [
+        "(3,53): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//WAPFORUM//DTD XHTML Mobile 1.0//EN\" \"http://www.wapforum.org/DTD/xhtml-mobile10.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE HTML SYSTEM \"http://www.w3.org/DTD/HTML4-strict.dtd\"><body><b>Mine!</b></body>",
+      "errors": [
+        "(1,63): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"\" \"http://www.w3.org/DTD/HTML4-strict.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "Mine!"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b>Mine!</b></body></html>",
+        "noQuirksBodyHtml": "<b>Mine!</b>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\">",
+      "errors": [
+        "(1,50): unexpected-char-in-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"'http://www.w3.org/TR/html4/strict.dtd'>",
+      "errors": [
+        "(1,50): unexpected-char-in-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE HTML PUBLIC\"-//W3C//DTD HTML 4.01//EN\"'http://www.w3.org/TR/html4/strict.dtd'>",
+      "errors": [
+        "(1,21): unexpected-char-in-doctype",
+        "(1,49): unexpected-char-in-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE HTML PUBLIC'-//W3C//DTD HTML 4.01//EN''http://www.w3.org/TR/html4/strict.dtd'>",
+      "errors": [
+        "(1,21): unexpected-char-in-doctype",
+        "(1,49): unexpected-char-in-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    }
+  ],
+  "domjs-unsafe.dat": [
+    {
+      "data": "<svg><![CDATA[foo\nbar]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(2,6): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo\nbar"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>foo\nbar</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo\nbar</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[foo\rbar]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(2,6): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo\nbar"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>foo\nbar</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo\nbar</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[foo\r\nbar]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(2,6): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo\nbar"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>foo\nbar</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo\nbar</svg>"
+      }
+    },
+    {
+      "data": "<script>a='\u0000'</script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,12): invalid-codepoint"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "a='�'",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script>a='�'</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script>a='�'</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--\u0000</script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,25): invalid-codepoint"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--�",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--�</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--�</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--foo\u0000</script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,28): invalid-codepoint"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--foo�",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--foo�</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--foo�</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!-- foo-\u0000</script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,30): invalid-codepoint"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!-- foo-�",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!-- foo-�</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!-- foo-�</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!-- foo--\u0000</script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,31): invalid-codepoint"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!-- foo--�",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!-- foo--�</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!-- foo--�</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!-- foo-",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,29): expected-script-data-but-got-eof",
+        "(1,29): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!-- foo-",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!-- foo-</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!-- foo-</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!-- foo-<</script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!-- foo-<",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!-- foo-<</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!-- foo-<</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!-- foo-<S",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,31): expected-script-data-but-got-eof",
+        "(1,31): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!-- foo-<S",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!-- foo-<S</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!-- foo-<S</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!-- foo-</SCRIPT>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!-- foo-",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!-- foo-</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!-- foo-</script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<p></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<p>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<p></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<p></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<script></script></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<script></script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<script></script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<script></script></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<script>\u0000</script></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,33): invalid-codepoint"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<script>�</script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<script>�</script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<script>�</script></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<script>-\u0000</script></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,34): invalid-codepoint"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<script>-�</script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<script>-�</script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<script>-�</script></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<script>--\u0000</script></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag",
+        "(1,35): invalid-codepoint"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<script>--�</script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<script>--�</script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<script>--�</script></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<script>---</script></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<script>---</script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<script>---</script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<script>---</script></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<script></scrip></SCRIPT></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<script></scrip></SCRIPT>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<script></scrip></SCRIPT></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<script></scrip></SCRIPT></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<script></scrip </SCRIPT></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<script></scrip </SCRIPT>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<script></scrip </SCRIPT></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<script></scrip </SCRIPT></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--<script></scrip/</SCRIPT></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--<script></scrip/</SCRIPT>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--<script></scrip/</SCRIPT></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--<script></scrip/</SCRIPT></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"></scrip/></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "</scrip/>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"></scrip/></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"></scrip/></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"></scrip ></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "</scrip >",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"></scrip ></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"></scrip ></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--</scrip></script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--</scrip>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--</scrip></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--</scrip></script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--</scrip </script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--</scrip ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--</scrip </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--</scrip </script>"
+      }
+    },
+    {
+      "data": "<script type=\"data\"><!--</scrip/</script>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "data"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "<!--</scrip/",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script type=\"data\"><!--</scrip/</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"data\"><!--</scrip/</script>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><!DOCTYPE html>",
+      "errors": [
+        "(1,30): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><!DOCTYPE html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,21): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head><!DOCTYPE html></head>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,27): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head></head><!DOCTYPE html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,34): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<body></body><!DOCTYPE html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,28): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<table><!DOCTYPE html></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,22): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table></table></body></html>",
+        "noQuirksBodyHtml": "<table></table>"
+      }
+    },
+    {
+      "data": "<select><!DOCTYPE html></select>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,23): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<table><colgroup><!DOCTYPE html></colgroup></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,32): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup></colgroup></table>"
+      }
+    },
+    {
+      "data": "<table><colgroup><!--test--></colgroup></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "comment": "test"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup><!--test--></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup><!--test--></colgroup></table>"
+      }
+    },
+    {
+      "data": "<table><colgroup><html></colgroup></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,23): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup></colgroup></table>"
+      }
+    },
+    {
+      "data": "<table><colgroup> foo</colgroup></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,32): foster-parenting-character-in-table",
+        "(1,32): foster-parenting-character-in-table",
+        "(1,32): foster-parenting-character-in-table",
+        "(1,32): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "foo"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "text": " "
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>foo<table><colgroup> </colgroup></table></body></html>",
+        "noQuirksBodyHtml": "foo<table><colgroup> </colgroup></table>"
+      }
+    },
+    {
+      "data": "<select><!--test--></select>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "comment": "test"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><!--test--></select></body></html>",
+        "noQuirksBodyHtml": "<select><!--test--></select>"
+      }
+    },
+    {
+      "data": "<select><html></select>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,14): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<frameset><html></frameset>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,16): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<frameset></frameset><html>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,27): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<frameset></frameset><!DOCTYPE html>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,36): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><body></body></html><!DOCTYPE html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,41): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<svg><!DOCTYPE html></svg>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,20): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg></body></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<svg><font></font></svg>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><font></font></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><font></font></svg>"
+      }
+    },
+    {
+      "data": "<svg><font id=foo></font></svg>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "foo"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><font id=\"foo\"></font></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><font id=\"foo\"></font></svg>"
+      }
+    },
+    {
+      "data": "<svg><font size=4></font></svg>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,18): unexpected-html-element-in-foreign-content",
+        "(1,31): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  },
+                  {
+                    "tag": "font",
+                    "attrs": [
+                      {
+                        "name": "size",
+                        "value": "4"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg><font size=\"4\"></font></body></html>",
+        "noQuirksBodyHtml": "<svg><font size=\"4\"></font></svg>"
+      }
+    },
+    {
+      "data": "<svg><font color=red></font></svg>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,21): unexpected-html-element-in-foreign-content",
+        "(1,34): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  },
+                  {
+                    "tag": "font",
+                    "attrs": [
+                      {
+                        "name": "color",
+                        "value": "red"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg><font color=\"red\"></font></body></html>",
+        "noQuirksBodyHtml": "<svg><font color=\"red\"></font></svg>"
+      }
+    },
+    {
+      "data": "<svg><font font=sans></font></svg>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "attrs": [
+                          {
+                            "name": "font",
+                            "value": "sans"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><font font=\"sans\"></font></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><font font=\"sans\"></font></svg>"
+      }
+    }
+  ],
+  "entities01.dat": [
+    {
+      "data": "FOO&gt;BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO>BAR",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&gt;BAR</body></html>",
+        "noQuirksBodyHtml": "FOO&gt;BAR"
+      }
+    },
+    {
+      "data": "FOO&gtBAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,6): named-entity-without-semicolon"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO>BAR",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&gt;BAR</body></html>",
+        "noQuirksBodyHtml": "FOO&gt;BAR"
+      }
+    },
+    {
+      "data": "FOO&gt BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,6): named-entity-without-semicolon"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO> BAR",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&gt; BAR</body></html>",
+        "noQuirksBodyHtml": "FOO&gt; BAR"
+      }
+    },
+    {
+      "data": "FOO&gt;;;BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO>;;BAR",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&gt;;;BAR</body></html>",
+        "noQuirksBodyHtml": "FOO&gt;;;BAR"
+      }
+    },
+    {
+      "data": "I'm &notit; I tell you",
+      "errors": [
+        "(1,4): expected-doctype-but-got-chars",
+        "(1,9): named-entity-without-semicolon"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "I'm ¬it; I tell you"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>I'm ¬it; I tell you</body></html>",
+        "noQuirksBodyHtml": "I'm ¬it; I tell you"
+      }
+    },
+    {
+      "data": "I'm &notin; I tell you",
+      "errors": [
+        "(1,4): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "I'm ∉ I tell you"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>I'm ∉ I tell you</body></html>",
+        "noQuirksBodyHtml": "I'm ∉ I tell you"
+      }
+    },
+    {
+      "data": "FOO& BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO& BAR",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&amp; BAR</body></html>",
+        "noQuirksBodyHtml": "FOO&amp; BAR"
+      }
+    },
+    {
+      "data": "FOO&<BAR>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,9): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "bar": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO&",
+                    "escaped": true
+                  },
+                  {
+                    "tag": "bar"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&amp;<bar></bar></body></html>",
+        "noQuirksBodyHtml": "FOO&amp;<bar></bar>"
+      }
+    },
+    {
+      "data": "FOO&&&&gt;BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO&&&>BAR",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&amp;&amp;&amp;&gt;BAR</body></html>",
+        "noQuirksBodyHtml": "FOO&amp;&amp;&amp;&gt;BAR"
+      }
+    },
+    {
+      "data": "FOO&#41;BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO)BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO)BAR</body></html>",
+        "noQuirksBodyHtml": "FOO)BAR"
+      }
+    },
+    {
+      "data": "FOO&#x41;BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOABAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOABAR</body></html>",
+        "noQuirksBodyHtml": "FOOABAR"
+      }
+    },
+    {
+      "data": "FOO&#X41;BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOABAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOABAR</body></html>",
+        "noQuirksBodyHtml": "FOOABAR"
+      }
+    },
+    {
+      "data": "FOO&#BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,5): expected-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO&#BAR",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&amp;#BAR</body></html>",
+        "noQuirksBodyHtml": "FOO&amp;#BAR"
+      }
+    },
+    {
+      "data": "FOO&#ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,5): expected-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO&#ZOO",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&amp;#ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO&amp;#ZOO"
+      }
+    },
+    {
+      "data": "FOO&#xBAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,7): expected-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOºR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOºR</body></html>",
+        "noQuirksBodyHtml": "FOOºR"
+      }
+    },
+    {
+      "data": "FOO&#xZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,6): expected-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO&#xZOO",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&amp;#xZOO</body></html>",
+        "noQuirksBodyHtml": "FOO&amp;#xZOO"
+      }
+    },
+    {
+      "data": "FOO&#XZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,6): expected-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO&#XZOO",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&amp;#XZOO</body></html>",
+        "noQuirksBodyHtml": "FOO&amp;#XZOO"
+      }
+    },
+    {
+      "data": "FOO&#41BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,7): numeric-entity-without-semicolon"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO)BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO)BAR</body></html>",
+        "noQuirksBodyHtml": "FOO)BAR"
+      }
+    },
+    {
+      "data": "FOO&#x41BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,10): numeric-entity-without-semicolon"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO䆺R"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO䆺R</body></html>",
+        "noQuirksBodyHtml": "FOO䆺R"
+      }
+    },
+    {
+      "data": "FOO&#x41ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,8): numeric-entity-without-semicolon"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOAZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOAZOO</body></html>",
+        "noQuirksBodyHtml": "FOOAZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0000;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0078;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOxZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOxZOO</body></html>",
+        "noQuirksBodyHtml": "FOOxZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0079;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOyZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOyZOO</body></html>",
+        "noQuirksBodyHtml": "FOOyZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0080;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO€ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO€ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO€ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0081;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO\81ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO\81ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO\81ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0082;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO‚ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO‚ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO‚ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0083;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOƒZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOƒZOO</body></html>",
+        "noQuirksBodyHtml": "FOOƒZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0084;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO„ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO„ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO„ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0085;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO…ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO…ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO…ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0086;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO†ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO†ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO†ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0087;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO‡ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO‡ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO‡ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0088;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOˆZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOˆZOO</body></html>",
+        "noQuirksBodyHtml": "FOOˆZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0089;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO‰ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO‰ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO‰ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x008A;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOŠZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOŠZOO</body></html>",
+        "noQuirksBodyHtml": "FOOŠZOO"
+      }
+    },
+    {
+      "data": "FOO&#x008B;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO‹ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO‹ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO‹ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x008C;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOŒZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOŒZOO</body></html>",
+        "noQuirksBodyHtml": "FOOŒZOO"
+      }
+    },
+    {
+      "data": "FOO&#x008D;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO\8dZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO\8dZOO</body></html>",
+        "noQuirksBodyHtml": "FOO\8dZOO"
+      }
+    },
+    {
+      "data": "FOO&#x008E;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOŽZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOŽZOO</body></html>",
+        "noQuirksBodyHtml": "FOOŽZOO"
+      }
+    },
+    {
+      "data": "FOO&#x008F;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO\8fZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO\8fZOO</body></html>",
+        "noQuirksBodyHtml": "FOO\8fZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0090;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO\90ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO\90ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO\90ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0091;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO‘ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO‘ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO‘ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0092;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO’ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO’ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO’ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0093;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO“ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO“ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO“ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0094;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO”ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO”ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO”ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0095;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO•ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO•ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO•ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0096;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO–ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO–ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO–ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0097;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO—ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO—ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO—ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0098;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO˜ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO˜ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO˜ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x0099;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO™ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO™ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO™ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x009A;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOšZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOšZOO</body></html>",
+        "noQuirksBodyHtml": "FOOšZOO"
+      }
+    },
+    {
+      "data": "FOO&#x009B;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO›ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO›ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO›ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x009C;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOœZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOœZOO</body></html>",
+        "noQuirksBodyHtml": "FOOœZOO"
+      }
+    },
+    {
+      "data": "FOO&#x009D;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO\9dZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO\9dZOO</body></html>",
+        "noQuirksBodyHtml": "FOO\9dZOO"
+      }
+    },
+    {
+      "data": "FOO&#x009E;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOžZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOžZOO</body></html>",
+        "noQuirksBodyHtml": "FOOžZOO"
+      }
+    },
+    {
+      "data": "FOO&#x009F;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOŸZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOŸZOO</body></html>",
+        "noQuirksBodyHtml": "FOOŸZOO"
+      }
+    },
+    {
+      "data": "FOO&#x00A0;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO ZOO",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO&nbsp;ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO&nbsp;ZOO"
+      }
+    },
+    {
+      "data": "FOO&#xD7FF;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO퟿ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO퟿ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO퟿ZOO"
+      }
+    },
+    {
+      "data": "FOO&#xD800;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#xD801;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#xDFFE;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#xDFFF;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#xE000;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOOZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOOZOO</body></html>",
+        "noQuirksBodyHtml": "FOOZOO"
+      }
+    },
+    {
+      "data": "FOO&#x10FFFE;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO􏿾ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO􏿾ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO􏿾ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x1087D4;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO􈟔ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO􈟔ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO􈟔ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x10FFFF;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO􏿿ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO􏿿ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO􏿿ZOO"
+      }
+    },
+    {
+      "data": "FOO&#x110000;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#xFFFFFF;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#11111111111",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity",
+        "(1,13): eof-in-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�</body></html>",
+        "noQuirksBodyHtml": "FOO�"
+      }
+    },
+    {
+      "data": "FOO&#1111111111",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity",
+        "(1,13): eof-in-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�</body></html>",
+        "noQuirksBodyHtml": "FOO�"
+      }
+    },
+    {
+      "data": "FOO&#111111111111",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity",
+        "(1,13): eof-in-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�</body></html>",
+        "noQuirksBodyHtml": "FOO�"
+      }
+    },
+    {
+      "data": "FOO&#11111111111ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#1111111111ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    },
+    {
+      "data": "FOO&#111111111111ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,13): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO�ZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO�ZOO</body></html>",
+        "noQuirksBodyHtml": "FOO�ZOO"
+      }
+    }
+  ],
+  "entities02.dat": [
+    {
+      "data": "<div bar=\"ZZ&gt;YY\"></div>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ>YY"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ>YY\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ>YY\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&\"></div>",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;\"></div>"
+      }
+    },
+    {
+      "data": "<div bar='ZZ&'></div>",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=ZZ&></div>",
+      "errors": [
+        "(1,13): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&gt=YY\"></div>",
+      "errors": [
+        "(1,15): named-entity-without-semicolon",
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&gt=YY",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;gt=YY\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;gt=YY\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&gt0YY\"></div>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&gt0YY",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;gt0YY\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;gt0YY\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&gt9YY\"></div>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&gt9YY",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;gt9YY\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;gt9YY\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&gtaYY\"></div>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&gtaYY",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;gtaYY\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;gtaYY\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&gtZYY\"></div>",
+      "errors": [
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&gtZYY",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;gtZYY\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;gtZYY\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&gt YY\"></div>",
+      "errors": [
+        "(1,15): named-entity-without-semicolon",
+        "(1,20): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ> YY"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ> YY\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ> YY\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&gt\"></div>",
+      "errors": [
+        "(1,15): named-entity-without-semicolon",
+        "(1,17): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ>"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ>\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ>\"></div>"
+      }
+    },
+    {
+      "data": "<div bar='ZZ&gt'></div>",
+      "errors": [
+        "(1,15): named-entity-without-semicolon",
+        "(1,17): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ>"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ>\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ>\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=ZZ&gt></div>",
+      "errors": [
+        "(1,14): named-entity-without-semicolon",
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ>"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ>\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ>\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&pound_id=23\"></div>",
+      "errors": [
+        "(1,18): named-entity-without-semicolon",
+        "(1,26): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ£_id=23"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ£_id=23\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ£_id=23\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&prod_id=23\"></div>",
+      "errors": [
+        "(1,25): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&prod_id=23",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;prod_id=23\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;prod_id=23\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&pound;_id=23\"></div>",
+      "errors": [
+        "(1,27): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ£_id=23"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ£_id=23\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ£_id=23\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&prod;_id=23\"></div>",
+      "errors": [
+        "(1,26): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ∏_id=23"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ∏_id=23\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ∏_id=23\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&pound=23\"></div>",
+      "errors": [
+        "(1,18): named-entity-without-semicolon",
+        "(1,23): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&pound=23",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;pound=23\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;pound=23\"></div>"
+      }
+    },
+    {
+      "data": "<div bar=\"ZZ&prod=23\"></div>",
+      "errors": [
+        "(1,22): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "ZZ&prod=23",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div bar=\"ZZ&amp;prod=23\"></div></body></html>",
+        "noQuirksBodyHtml": "<div bar=\"ZZ&amp;prod=23\"></div>"
+      }
+    },
+    {
+      "data": "<div>ZZ&pound_id=23</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,13): named-entity-without-semicolon"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "ZZ£_id=23"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>ZZ£_id=23</div></body></html>",
+        "noQuirksBodyHtml": "<div>ZZ£_id=23</div>"
+      }
+    },
+    {
+      "data": "<div>ZZ&prod_id=23</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "ZZ&prod_id=23",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>ZZ&amp;prod_id=23</div></body></html>",
+        "noQuirksBodyHtml": "<div>ZZ&amp;prod_id=23</div>"
+      }
+    },
+    {
+      "data": "<div>ZZ&pound;_id=23</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "ZZ£_id=23"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>ZZ£_id=23</div></body></html>",
+        "noQuirksBodyHtml": "<div>ZZ£_id=23</div>"
+      }
+    },
+    {
+      "data": "<div>ZZ&prod;_id=23</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "ZZ∏_id=23"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>ZZ∏_id=23</div></body></html>",
+        "noQuirksBodyHtml": "<div>ZZ∏_id=23</div>"
+      }
+    },
+    {
+      "data": "<div>ZZ&pound=23</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,13): named-entity-without-semicolon"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "ZZ£=23"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>ZZ£=23</div></body></html>",
+        "noQuirksBodyHtml": "<div>ZZ£=23</div>"
+      }
+    },
+    {
+      "data": "<div>ZZ&prod=23</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "ZZ&prod=23",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>ZZ&amp;prod=23</div></body></html>",
+        "noQuirksBodyHtml": "<div>ZZ&amp;prod=23</div>"
+      }
+    },
+    {
+      "data": "<div>ZZ&AElig=</div>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "ZZÆ="
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>ZZÆ=</div></body></html>",
+        "noQuirksBodyHtml": "<div>ZZÆ=</div>"
+      }
+    }
+  ],
+  "foreign-fragment.dat": [
+    {
+      "data": "<nobr>X",
+      "errors": [
+        "6: HTML start tag “nobr” in a foreign namespace context.",
+        "7: End of file seen and there were open elements.",
+        "6: Unclosed element “nobr”."
+      ],
+      "fragment": {
+        "name": "path",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "svg nobr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "nobr",
+            "ns": "http://www.w3.org/2000/svg",
+            "children": [
+              {
+                "text": "X"
+              }
+            ]
+          }
+        ],
+        "html": "<nobr>X</nobr>",
+        "noQuirksBodyHtml": "<nobr>X</nobr>"
+      }
+    },
+    {
+      "data": "<font color></font>X",
+      "errors": [
+        "12: HTML start tag “font” in a foreign namespace context."
+      ],
+      "fragment": {
+        "name": "path",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "svg font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "font",
+            "ns": "http://www.w3.org/2000/svg",
+            "attrs": [
+              {
+                "name": "color",
+                "value": ""
+              }
+            ]
+          },
+          {
+            "text": "X"
+          }
+        ],
+        "html": "<font color=\"\"></font>X",
+        "noQuirksBodyHtml": "<font color=\"\"></font>X"
+      }
+    },
+    {
+      "data": "<font></font>X",
+      "errors": [],
+      "fragment": {
+        "name": "path",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "svg font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "font",
+            "ns": "http://www.w3.org/2000/svg"
+          },
+          {
+            "text": "X"
+          }
+        ],
+        "html": "<font></font>X",
+        "noQuirksBodyHtml": "<font></font>X"
+      }
+    },
+    {
+      "data": "<g></path>X",
+      "errors": [
+        "10: End tag “path” did not match the name of the current open element (“g”).",
+        "11: End of file seen and there were open elements.",
+        "3: Unclosed element “g”."
+      ],
+      "fragment": {
+        "name": "path",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "svg g": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "g",
+            "ns": "http://www.w3.org/2000/svg",
+            "children": [
+              {
+                "text": "X"
+              }
+            ]
+          }
+        ],
+        "html": "<g>X</g>",
+        "noQuirksBodyHtml": "<g>X</g>"
+      }
+    },
+    {
+      "data": "</path>X",
+      "errors": [
+        "5: Stray end tag “path”."
+      ],
+      "fragment": {
+        "name": "path",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</foreignObject>X",
+      "errors": [
+        "5: Stray end tag “foreignobject”."
+      ],
+      "fragment": {
+        "name": "foreignObject",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</desc>X",
+      "errors": [
+        "5: Stray end tag “desc”."
+      ],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</title>X",
+      "errors": [
+        "5: Stray end tag “title”."
+      ],
+      "fragment": {
+        "name": "title",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</svg>X",
+      "errors": [
+        "5: Stray end tag “svg”."
+      ],
+      "fragment": {
+        "name": "svg",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</mfenced>X",
+      "errors": [
+        "5: Stray end tag “mfenced”."
+      ],
+      "fragment": {
+        "name": "mfenced",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</malignmark>X",
+      "errors": [
+        "5: Stray end tag “malignmark”."
+      ],
+      "fragment": {
+        "name": "malignmark",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</math>X",
+      "errors": [
+        "5: Stray end tag “math”."
+      ],
+      "fragment": {
+        "name": "math",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</annotation-xml>X",
+      "errors": [
+        "5: Stray end tag “annotation-xml”."
+      ],
+      "fragment": {
+        "name": "annotation-xml",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</mtext>X",
+      "errors": [
+        "5: Stray end tag “mtext”."
+      ],
+      "fragment": {
+        "name": "mtext",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</mi>X",
+      "errors": [
+        "5: Stray end tag “mi”."
+      ],
+      "fragment": {
+        "name": "mi",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</mo>X",
+      "errors": [
+        "5: Stray end tag “mo”."
+      ],
+      "fragment": {
+        "name": "mo",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</mn>X",
+      "errors": [
+        "5: Stray end tag “mn”."
+      ],
+      "fragment": {
+        "name": "mn",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "</ms>X",
+      "errors": [
+        "5: Stray end tag “ms”."
+      ],
+      "fragment": {
+        "name": "ms",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<b></b><mglyph/><i></i><malignmark/><u></u><ms/>X",
+      "errors": [
+        "51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.",
+        "52: End of file seen and there were open elements.",
+        "51: Unclosed element “ms”."
+      ],
+      "fragment": {
+        "name": "ms",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "b": true,
+            "math mglyph": true,
+            "i": true,
+            "math malignmark": true,
+            "u": true,
+            "ms": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "b"
+          },
+          {
+            "tag": "mglyph",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "i"
+          },
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "u"
+          },
+          {
+            "tag": "ms",
+            "children": [
+              {
+                "text": "X"
+              }
+            ]
+          }
+        ],
+        "html": "<b></b><mglyph></mglyph><i></i><malignmark></malignmark><u></u><ms>X</ms>",
+        "noQuirksBodyHtml": "<b></b><mglyph><i></i><malignmark><u></u><ms>X</ms></malignmark></mglyph>"
+      }
+    },
+    {
+      "data": "<malignmark></malignmark>",
+      "errors": [],
+      "fragment": {
+        "name": "ms",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<malignmark></malignmark>",
+        "noQuirksBodyHtml": "<malignmark></malignmark>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [],
+      "fragment": {
+        "name": "ms",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "ms",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<b></b><mglyph/><i></i><malignmark/><u></u><mn/>X",
+      "errors": [
+        "51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.",
+        "52: End of file seen and there were open elements.",
+        "51: Unclosed element “mn”."
+      ],
+      "fragment": {
+        "name": "mn",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "b": true,
+            "math mglyph": true,
+            "i": true,
+            "math malignmark": true,
+            "u": true,
+            "mn": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "b"
+          },
+          {
+            "tag": "mglyph",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "i"
+          },
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "u"
+          },
+          {
+            "tag": "mn",
+            "children": [
+              {
+                "text": "X"
+              }
+            ]
+          }
+        ],
+        "html": "<b></b><mglyph></mglyph><i></i><malignmark></malignmark><u></u><mn>X</mn>",
+        "noQuirksBodyHtml": "<b></b><mglyph><i></i><malignmark><u></u><mn>X</mn></malignmark></mglyph>"
+      }
+    },
+    {
+      "data": "<malignmark></malignmark>",
+      "errors": [],
+      "fragment": {
+        "name": "mn",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<malignmark></malignmark>",
+        "noQuirksBodyHtml": "<malignmark></malignmark>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [],
+      "fragment": {
+        "name": "mn",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "mn",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<b></b><mglyph/><i></i><malignmark/><u></u><mo/>X",
+      "errors": [
+        "51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.",
+        "52: End of file seen and there were open elements.",
+        "51: Unclosed element “mo”."
+      ],
+      "fragment": {
+        "name": "mo",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "b": true,
+            "math mglyph": true,
+            "i": true,
+            "math malignmark": true,
+            "u": true,
+            "mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "b"
+          },
+          {
+            "tag": "mglyph",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "i"
+          },
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "u"
+          },
+          {
+            "tag": "mo",
+            "children": [
+              {
+                "text": "X"
+              }
+            ]
+          }
+        ],
+        "html": "<b></b><mglyph></mglyph><i></i><malignmark></malignmark><u></u><mo>X</mo>",
+        "noQuirksBodyHtml": "<b></b><mglyph><i></i><malignmark><u></u><mo>X</mo></malignmark></mglyph>"
+      }
+    },
+    {
+      "data": "<malignmark></malignmark>",
+      "errors": [],
+      "fragment": {
+        "name": "mo",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<malignmark></malignmark>",
+        "noQuirksBodyHtml": "<malignmark></malignmark>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [],
+      "fragment": {
+        "name": "mo",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "mo",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<b></b><mglyph/><i></i><malignmark/><u></u><mi/>X",
+      "errors": [
+        "51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.",
+        "52: End of file seen and there were open elements.",
+        "51: Unclosed element “mi”."
+      ],
+      "fragment": {
+        "name": "mi",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "b": true,
+            "math mglyph": true,
+            "i": true,
+            "math malignmark": true,
+            "u": true,
+            "mi": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "b"
+          },
+          {
+            "tag": "mglyph",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "i"
+          },
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "u"
+          },
+          {
+            "tag": "mi",
+            "children": [
+              {
+                "text": "X"
+              }
+            ]
+          }
+        ],
+        "html": "<b></b><mglyph></mglyph><i></i><malignmark></malignmark><u></u><mi>X</mi>",
+        "noQuirksBodyHtml": "<b></b><mglyph><i></i><malignmark><u></u><mi>X</mi></malignmark></mglyph>"
+      }
+    },
+    {
+      "data": "<malignmark></malignmark>",
+      "errors": [],
+      "fragment": {
+        "name": "mi",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<malignmark></malignmark>",
+        "noQuirksBodyHtml": "<malignmark></malignmark>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [],
+      "fragment": {
+        "name": "mi",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "mi",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<b></b><mglyph/><i></i><malignmark/><u></u><mtext/>X",
+      "errors": [
+        "51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.",
+        "52: End of file seen and there were open elements.",
+        "51: Unclosed element “mtext”."
+      ],
+      "fragment": {
+        "name": "mtext",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "b": true,
+            "math mglyph": true,
+            "i": true,
+            "math malignmark": true,
+            "u": true,
+            "mtext": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "b"
+          },
+          {
+            "tag": "mglyph",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "i"
+          },
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          },
+          {
+            "tag": "u"
+          },
+          {
+            "tag": "mtext",
+            "children": [
+              {
+                "text": "X"
+              }
+            ]
+          }
+        ],
+        "html": "<b></b><mglyph></mglyph><i></i><malignmark></malignmark><u></u><mtext>X</mtext>",
+        "noQuirksBodyHtml": "<b></b><mglyph><i></i><malignmark><u></u><mtext>X</mtext></malignmark></mglyph>"
+      }
+    },
+    {
+      "data": "<malignmark></malignmark>",
+      "errors": [],
+      "fragment": {
+        "name": "mtext",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "malignmark",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<malignmark></malignmark>",
+        "noQuirksBodyHtml": "<malignmark></malignmark>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [],
+      "fragment": {
+        "name": "mtext",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "mtext",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [
+        "5: HTML start tag “div” in a foreign namespace context."
+      ],
+      "fragment": {
+        "name": "annotation-xml",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "annotation-xml",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [
+        "5: HTML start tag “div” in a foreign namespace context."
+      ],
+      "fragment": {
+        "name": "math",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "math",
+        "ns": "http://www.w3.org/1998/Math/MathML"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure",
+            "ns": "http://www.w3.org/1998/Math/MathML"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [],
+      "fragment": {
+        "name": "foreignObject",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "foreignObject",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [],
+      "fragment": {
+        "name": "title",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "title",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<div><h1>X</h1></div>",
+      "errors": [
+        "5: HTML start tag “div” in a foreign namespace context.",
+        "9: HTML start tag “h1” in a foreign namespace context."
+      ],
+      "fragment": {
+        "name": "svg",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "svg div": true,
+            "svg h1": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div",
+            "ns": "http://www.w3.org/2000/svg",
+            "children": [
+              {
+                "tag": "h1",
+                "ns": "http://www.w3.org/2000/svg",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<div><h1>X</h1></div>",
+        "noQuirksBodyHtml": "<div><h1>X</h1></div>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [
+        "5: HTML start tag “div” in a foreign namespace context."
+      ],
+      "fragment": {
+        "name": "svg",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "svg div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div",
+            "ns": "http://www.w3.org/2000/svg"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<figure></figure>",
+      "errors": [],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "figure": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "figure"
+          }
+        ],
+        "html": "<figure></figure>",
+        "noQuirksBodyHtml": "<figure></figure>"
+      }
+    },
+    {
+      "data": "<plaintext><foo>",
+      "errors": [
+        "16: End of file seen and there were open elements.",
+        "11: Unclosed element “plaintext”."
+      ],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "plaintext": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "plaintext",
+            "children": [
+              {
+                "text": "<foo>",
+                "no_escape": true
+              }
+            ]
+          }
+        ],
+        "html": "<plaintext><foo></plaintext>",
+        "noQuirksBodyHtml": "<plaintext><foo></plaintext>"
+      }
+    },
+    {
+      "data": "<frameset>X",
+      "errors": [
+        "6: Stray start tag “frameset”."
+      ],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<head>X",
+      "errors": [
+        "6: Stray start tag “head”."
+      ],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<body>X",
+      "errors": [
+        "6: Stray start tag “body”."
+      ],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<html>X",
+      "errors": [
+        "6: Stray start tag “html”."
+      ],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<html class=\"foo\">X",
+      "errors": [
+        "6: Stray start tag “html”."
+      ],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<body class=\"foo\">X",
+      "errors": [
+        "6: Stray start tag “body”."
+      ],
+      "fragment": {
+        "name": "desc",
+        "ns": "http://www.w3.org/2000/svg"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "X"
+          }
+        ],
+        "html": "X",
+        "noQuirksBodyHtml": "X"
+      }
+    }
+  ],
+  "html5test-com.dat": [
+    {
+      "data": "<div<div>",
+      "errors": [
+        "(1,9): expected-doctype-but-got-start-tag",
+        "(1,9): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div<div": true
+          },
+          "tagWithLt": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div<div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div<div></div<div></body></html>",
+        "noQuirksBodyHtml": "<div<div></div<div>"
+      }
+    },
+    {
+      "data": "<div foo<bar=''>",
+      "errors": [
+        "(1,9): invalid-character-in-attribute-name",
+        "(1,16): expected-doctype-but-got-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "attrWithFunnyChar": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "foo<bar",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div foo<bar=\"\"></div></body></html>",
+        "noQuirksBodyHtml": "<div foo<bar=\"\"></div>"
+      }
+    },
+    {
+      "data": "<div foo=`bar`>",
+      "errors": [
+        "(1,10): equals-in-unquoted-attribute-value",
+        "(1,14): unexpected-character-in-unquoted-attribute-value",
+        "(1,15): expected-doctype-but-got-start-tag",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "foo",
+                        "value": "`bar`"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div foo=\"`bar`\"></div></body></html>",
+        "noQuirksBodyHtml": "<div foo=\"`bar`\"></div>"
+      }
+    },
+    {
+      "data": "<div \\\"foo=''>",
+      "errors": [
+        "(1,7): invalid-character-in-attribute-name",
+        "(1,14): expected-doctype-but-got-start-tag",
+        "(1,14): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "attrWithFunnyChar": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "\\\"foo",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div \\\"foo=\"\"></div></body></html>",
+        "noQuirksBodyHtml": "<div \\\"foo=\"\"></div>"
+      }
+    },
+    {
+      "data": "<a href='\\nbar'></a>",
+      "errors": [
+        "(1,16): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "\\nbar"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a href=\"\\nbar\"></a></body></html>",
+        "noQuirksBodyHtml": "<a href=\"\\nbar\"></a>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "&lang;&rang;",
+      "errors": [
+        "(1,6): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "⟨⟩"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>⟨⟩</body></html>",
+        "noQuirksBodyHtml": "⟨⟩"
+      }
+    },
+    {
+      "data": "&apos;",
+      "errors": [
+        "(1,6): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "'"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>'</body></html>",
+        "noQuirksBodyHtml": "'"
+      }
+    },
+    {
+      "data": "&ImaginaryI;",
+      "errors": [
+        "(1,12): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "ⅈ"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>ⅈ</body></html>",
+        "noQuirksBodyHtml": "ⅈ"
+      }
+    },
+    {
+      "data": "&Kopf;",
+      "errors": [
+        "(1,6): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "𝕂"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>𝕂</body></html>",
+        "noQuirksBodyHtml": "𝕂"
+      }
+    },
+    {
+      "data": "&notinva;",
+      "errors": [
+        "(1,9): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "∉"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>∉</body></html>",
+        "noQuirksBodyHtml": "∉"
+      }
+    },
+    {
+      "data": "<?import namespace=\"foo\" implementation=\"#bar\">",
+      "errors": [
+        "(1,1): expected-tag-name-but-got-question-mark",
+        "(1,47): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "?import namespace=\"foo\" implementation=\"#bar\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--?import namespace=\"foo\" implementation=\"#bar\"--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--?import namespace=\"foo\" implementation=\"#bar\"-->"
+      }
+    },
+    {
+      "data": "<!--foo--bar-->",
+      "errors": [
+        "(1,10): unexpected-char-in-comment",
+        "(1,15): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "foo--bar"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--foo--bar--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--foo--bar-->"
+      }
+    },
+    {
+      "data": "<![CDATA[x]]>",
+      "errors": [
+        "(1,2): expected-dashes-or-doctype",
+        "(1,13): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "[CDATA[x]]"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--[CDATA[x]]--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--[CDATA[x]]-->"
+      }
+    },
+    {
+      "data": "<textarea><!--</textarea>--></textarea>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,39): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "escaped": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><textarea>&lt;!--</textarea>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<textarea>&lt;!--</textarea>--&gt;"
+      }
+    },
+    {
+      "data": "<textarea><!--</textarea>-->",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "escaped": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><textarea>&lt;!--</textarea>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<textarea>&lt;!--</textarea>--&gt;"
+      }
+    },
+    {
+      "data": "<style><!--</style>--></style>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,30): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--</style></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<style><!--</style>--&gt;"
+      }
+    },
+    {
+      "data": "<style><!--</style>-->",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--</style></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<style><!--</style>--&gt;"
+      }
+    },
+    {
+      "data": "<ul><li>A </li> <li>B</li></ul>",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ul": true,
+            "li": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ul",
+                    "children": [
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "text": "A "
+                          }
+                        ]
+                      },
+                      {
+                        "text": " "
+                      },
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "text": "B"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ul><li>A </li> <li>B</li></ul></body></html>",
+        "noQuirksBodyHtml": "<ul><li>A </li> <li>B</li></ul>"
+      }
+    },
+    {
+      "data": "<table><form><input type=hidden><input></form><div></div></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,13): unexpected-form-in-table",
+        "(1,32): unexpected-hidden-input-in-table",
+        "(1,39): unexpected-start-tag-implies-table-voodoo",
+        "(1,46): unexpected-end-tag-implies-table-voodoo",
+        "(1,46): unexpected-end-tag",
+        "(1,51): unexpected-start-tag-implies-table-voodoo",
+        "(1,57): unexpected-end-tag-implies-table-voodoo"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "input": true,
+            "div": true,
+            "table": true,
+            "form": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "input"
+                  },
+                  {
+                    "tag": "div"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "form"
+                      },
+                      {
+                        "tag": "input",
+                        "attrs": [
+                          {
+                            "name": "type",
+                            "value": "hidden"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><input><div></div><table><form></form><input type=\"hidden\"></table></body></html>",
+        "noQuirksBodyHtml": "<input><div></div><table><form></form><input type=\"hidden\"></table>"
+      }
+    },
+    {
+      "data": "<i>A<b>B<p></i>C</b>D",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,15): adoption-agency-1.3",
+        "(1,20): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "i": true,
+            "b": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": "A"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "B"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "i"
+                          },
+                          {
+                            "text": "C"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "D"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><i>A<b>B</b></i><b></b><p><b><i></i>C</b>D</p></body></html>",
+        "noQuirksBodyHtml": "<i>A<b>B</b></i><b></b><p><b><i></i>C</b>D</p>"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div></div></body></html>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<svg></svg>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg></body></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<math></math>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math></math></body></html>",
+        "noQuirksBodyHtml": "<math></math>"
+      }
+    }
+  ],
+  "inbody01.dat": [
+    {
+      "data": "<button>1</foo>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,15): unexpected-end-tag",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "button": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "button",
+                    "children": [
+                      {
+                        "text": "1"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><button>1</button></body></html>",
+        "noQuirksBodyHtml": "<button>1</button>"
+      }
+    },
+    {
+      "data": "<foo>1<p>2</foo>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,16): unexpected-end-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "foo": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "children": [
+                      {
+                        "text": "1"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><foo>1<p>2</p></foo></body></html>",
+        "noQuirksBodyHtml": "<foo>1<p>2</p></foo>"
+      }
+    },
+    {
+      "data": "<dd>1</foo>",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dd": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dd",
+                    "children": [
+                      {
+                        "text": "1"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><dd>1</dd></body></html>",
+        "noQuirksBodyHtml": "<dd>1</dd>"
+      }
+    },
+    {
+      "data": "<foo>1<dd>2</foo>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,17): unexpected-end-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "foo": true,
+            "dd": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "children": [
+                      {
+                        "text": "1"
+                      },
+                      {
+                        "tag": "dd",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><foo>1<dd>2</dd></foo></body></html>",
+        "noQuirksBodyHtml": "<foo>1<dd>2</dd></foo>"
+      }
+    }
+  ],
+  "isindex.dat": [
+    {
+      "data": "<isindex>",
+      "errors": [
+        "(1,9): expected-doctype-but-got-start-tag",
+        "(1,9): deprecated-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "hr": true,
+            "label": true,
+            "input": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "hr"
+                      },
+                      {
+                        "tag": "label",
+                        "children": [
+                          {
+                            "text": "This is a searchable index. Enter search keywords: "
+                          },
+                          {
+                            "tag": "input",
+                            "attrs": [
+                              {
+                                "name": "name",
+                                "value": "isindex"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "hr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form></body></html>",
+        "noQuirksBodyHtml": "<form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>"
+      }
+    },
+    {
+      "data": "<isindex name=\"A\" action=\"B\" prompt=\"C\" foo=\"D\">",
+      "errors": [
+        "(1,48): expected-doctype-but-got-start-tag",
+        "(1,48): deprecated-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "hr": true,
+            "label": true,
+            "input": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "attrs": [
+                      {
+                        "name": "action",
+                        "value": "B"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "hr"
+                      },
+                      {
+                        "tag": "label",
+                        "children": [
+                          {
+                            "text": "C"
+                          },
+                          {
+                            "tag": "input",
+                            "attrs": [
+                              {
+                                "name": "foo",
+                                "value": "D"
+                              },
+                              {
+                                "name": "name",
+                                "value": "isindex"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "hr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><form action=\"B\"><hr><label>C<input name=\"isindex\" foo=\"D\"></label><hr></form></body></html>",
+        "noQuirksBodyHtml": "<form action=\"B\"><hr><label>C<input name=\"isindex\" foo=\"D\"></label><hr></form>"
+      }
+    },
+    {
+      "data": "<form><isindex>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,15): deprecated-tag",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><form></form></body></html>",
+        "noQuirksBodyHtml": "<form></form>"
+      }
+    }
+  ],
+  "main-element.dat": [
+    {
+      "data": "<!doctype html><p>foo<main>bar<p>baz",
+      "errors": [
+        "(1,36): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "main": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "main",
+                    "children": [
+                      {
+                        "text": "bar"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "baz"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p>foo</p><main>bar<p>baz</p></main></body></html>",
+        "noQuirksBodyHtml": "<p>foo</p><main>bar<p>baz</p></main>"
+      }
+    },
+    {
+      "data": "<!doctype html><main><p>foo</main>bar",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "main": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "main",
+                    "children": [
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "bar"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><main><p>foo</p></main>bar</body></html>",
+        "noQuirksBodyHtml": "<main><p>foo</p></main>bar"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>xxx<svg><x><g><a><main><b>",
+      "errors": [
+        " * (1,42) unexpected HTML-like start tag token in foreign content",
+        " * (1,42) unexpected end of file"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg x": true,
+            "svg g": true,
+            "svg a": true,
+            "svg main": true,
+            "b": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "xxx"
+                  },
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "x",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "g",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "a",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "main",
+                                    "ns": "http://www.w3.org/2000/svg"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>xxx<svg><x><g><a><main></main></a></g></x></svg><b></b></body></html>",
+        "noQuirksBodyHtml": "xxx<svg><x><g><a><main><b></b></main></a></g></x></svg>"
+      }
+    }
+  ],
+  "math.dat": [
+    {
+      "data": "<math><tr><td><mo><tr>",
+      "errors": [],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tr": true,
+            "math td": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tr",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "td",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mo",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tr><td><mo></mo></td></tr></math>",
+        "noQuirksBodyHtml": "<math><tr><td><mo></mo></td></tr></math>"
+      }
+    },
+    {
+      "data": "<math><tr><td><mo><tr>",
+      "errors": [],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tr": true,
+            "math td": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tr",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "td",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mo",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tr><td><mo></mo></td></tr></math>",
+        "noQuirksBodyHtml": "<math><tr><td><mo></mo></td></tr></math>"
+      }
+    },
+    {
+      "data": "<math><thead><mo><tbody>",
+      "errors": [],
+      "fragment": {
+        "name": "thead"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math thead": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "thead",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><thead><mo></mo></thead></math>",
+        "noQuirksBodyHtml": "<math><thead><mo></mo></thead></math>"
+      }
+    },
+    {
+      "data": "<math><tfoot><mo><tbody>",
+      "errors": [],
+      "fragment": {
+        "name": "tfoot"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tfoot": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tfoot",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tfoot><mo></mo></tfoot></math>",
+        "noQuirksBodyHtml": "<math><tfoot><mo></mo></tfoot></math>"
+      }
+    },
+    {
+      "data": "<math><tbody><mo><tfoot>",
+      "errors": [],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tbody": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tbody",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tbody><mo></mo></tbody></math>",
+        "noQuirksBodyHtml": "<math><tbody><mo></mo></tbody></math>"
+      }
+    },
+    {
+      "data": "<math><tbody><mo></table>",
+      "errors": [],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tbody": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tbody",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tbody><mo></mo></tbody></math>",
+        "noQuirksBodyHtml": "<math><tbody><mo></mo></tbody></math>"
+      }
+    },
+    {
+      "data": "<math><thead><mo></table>",
+      "errors": [],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math thead": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "thead",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><thead><mo></mo></thead></math>",
+        "noQuirksBodyHtml": "<math><thead><mo></mo></thead></math>"
+      }
+    },
+    {
+      "data": "<math><tfoot><mo></table>",
+      "errors": [],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tfoot": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tfoot",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tfoot><mo></mo></tfoot></math>",
+        "noQuirksBodyHtml": "<math><tfoot><mo></mo></tfoot></math>"
+      }
+    }
+  ],
+  "namespace-sensitivity.dat": [
+    {
+      "data": "<body><table><tr><td><svg><td><foreignObject><span></td>Foo",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg td": true,
+            "svg foreignObject": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Foo"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "td",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "tag": "foreignObject",
+                                            "ns": "http://www.w3.org/2000/svg",
+                                            "children": [
+                                              {
+                                                "tag": "span"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>Foo<table><tbody><tr><td><svg><td><foreignObject><span></span></foreignObject></td></svg></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "Foo<table><tbody><tr><td><svg><td><foreignObject><span></span></foreignObject></td></svg></td></tr></tbody></table>"
+      }
+    }
+  ],
+  "pending-spec-changes-plain-text-unsafe.dat": [
+    {
+      "data": "<body><table>\u0000filler\u0000text\u0000",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,14): invalid-codepoint",
+        "(1,14): invalid-codepoint-in-table-text",
+        "(1,21): invalid-codepoint",
+        "(1,21): invalid-codepoint-in-table-text",
+        "(1,26): invalid-codepoint",
+        "(1,26): invalid-codepoint-in-table-text",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): foster-parenting-character-in-table",
+        "(1,26): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "fillertext"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>fillertext<table></table></body></html>",
+        "noQuirksBodyHtml": "fillertext<table></table>"
+      }
+    }
+  ],
+  "pending-spec-changes.dat": [
+    {
+      "data": "<input type=\"hidden\"><frameset>",
+      "errors": [
+        "(1,21): expected-doctype-but-got-start-tag",
+        "(1,31): unexpected-start-tag",
+        "(1,31): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<input type=\"hidden\">"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><table><caption><svg>foo</table>bar",
+      "errors": [
+        "(1,47): unexpected-end-tag",
+        "(1,47): end-table-tag-in-caption"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "text": "foo"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "bar"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><svg>foo</svg></caption></table>bar</body></html>",
+        "noQuirksBodyHtml": "<table><caption><svg>foo</svg></caption></table>bar"
+      }
+    },
+    {
+      "data": "<table><tr><td><svg><desc><td></desc><circle>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,30): unexpected-cell-end-tag",
+        "(1,37): unexpected-end-tag",
+        "(1,45): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg desc": true,
+            "circle": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "desc",
+                                        "ns": "http://www.w3.org/2000/svg"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "circle"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td><svg><desc></desc></svg></td><td><circle></circle></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><svg><desc></desc></svg></td><td><circle></circle></td></tr></tbody></table>"
+      }
+    }
+  ],
+  "plain-text-unsafe.dat": [
+    {
+      "data": "FOO&#x000D;ZOO",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,11): illegal-codepoint-for-numeric-entity"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO\rZOO"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO\rZOO</body></html>",
+        "noQuirksBodyHtml": "FOO\rZOO"
+      }
+    },
+    {
+      "data": "<html>\u0000<frameset></frameset>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,7): invalid-codepoint",
+        "(1,7): invalid-codepoint-in-body",
+        "(1,17): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html> \u0000 <frameset></frameset>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,8): invalid-codepoint",
+        "(1,8): invalid-codepoint-in-body",
+        "(1,19): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "  "
+      }
+    },
+    {
+      "data": "<html>a\u0000a<frameset></frameset>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,8): invalid-codepoint",
+        "(1,8): invalid-codepoint-in-body",
+        "(1,19): unexpected-start-tag",
+        "(1,30): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "aa"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>aa</body></html>",
+        "noQuirksBodyHtml": "aa"
+      }
+    },
+    {
+      "data": "<html>\u0000\u0000<frameset></frameset>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,7): invalid-codepoint",
+        "(1,7): invalid-codepoint-in-body",
+        "(1,8): invalid-codepoint",
+        "(1,8): invalid-codepoint-in-body",
+        "(1,18): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html>\u0000\n <frameset></frameset>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,7): invalid-codepoint",
+        "(1,7): invalid-codepoint-in-body",
+        "(2,11): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "\n "
+      }
+    },
+    {
+      "data": "<html><select>\u0000",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,15): invalid-codepoint",
+        "(1,15): invalid-codepoint-in-select",
+        "(1,15): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "\u0000",
+      "errors": [
+        "(1,1): invalid-codepoint",
+        "(1,1): expected-doctype-but-got-chars",
+        "(1,1): invalid-codepoint-in-body"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<body>\u0000",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,7): invalid-codepoint",
+        "(1,7): invalid-codepoint-in-body"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<plaintext>\u0000filler\u0000text\u0000",
+      "errors": [
+        "(1,11): expected-doctype-but-got-start-tag",
+        "(1,12): invalid-codepoint",
+        "(1,19): invalid-codepoint",
+        "(1,24): invalid-codepoint",
+        "(1,24): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "plaintext": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "text": "�filler�text�",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><plaintext>�filler�text�</plaintext></body></html>",
+        "noQuirksBodyHtml": "<plaintext>�filler�text�</plaintext>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[\u0000filler\u0000text\u0000]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,30): invalid-codepoint",
+        "(1,30): invalid-codepoint",
+        "(1,30): invalid-codepoint",
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "�filler�text�"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>�filler�text�</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>�filler�text�</svg>"
+      }
+    },
+    {
+      "data": "<body><!\u0000>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,8): expected-dashes-or-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "comment": "�"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><!--�--></body></html>",
+        "noQuirksBodyHtml": "<!--�-->"
+      }
+    },
+    {
+      "data": "<body><!\u0000filler\u0000text>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,8): expected-dashes-or-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "comment": "�filler�text"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><!--�filler�text--></body></html>",
+        "noQuirksBodyHtml": "<!--�filler�text-->"
+      }
+    },
+    {
+      "data": "<body><svg><foreignObject>\u0000filler\u0000text",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,27): invalid-codepoint",
+        "(1,27): invalid-codepoint-in-body",
+        "(1,34): invalid-codepoint",
+        "(1,34): invalid-codepoint-in-body",
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg foreignObject": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "fillertext"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><foreignObject>fillertext</foreignObject></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><foreignObject>fillertext</foreignObject></svg>"
+      }
+    },
+    {
+      "data": "<svg>\u0000filler\u0000text",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,6): invalid-codepoint",
+        "(1,6): invalid-codepoint-in-foreign-content",
+        "(1,13): invalid-codepoint",
+        "(1,13): invalid-codepoint-in-foreign-content",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "�filler�text"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>�filler�text</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>�filler�text</svg>"
+      }
+    },
+    {
+      "data": "<svg>\u0000<frameset>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,6): invalid-codepoint",
+        "(1,6): invalid-codepoint-in-foreign-content",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "�"
+                      },
+                      {
+                        "tag": "frameset",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>�<frameset></frameset></svg></body></html>",
+        "noQuirksBodyHtml": "<svg>�<frameset></frameset></svg>"
+      }
+    },
+    {
+      "data": "<svg>\u0000 <frameset>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,6): invalid-codepoint",
+        "(1,6): invalid-codepoint-in-foreign-content",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "� "
+                      },
+                      {
+                        "tag": "frameset",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>� <frameset></frameset></svg></body></html>",
+        "noQuirksBodyHtml": "<svg>� <frameset></frameset></svg>"
+      }
+    },
+    {
+      "data": "<svg>\u0000a<frameset>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,6): invalid-codepoint",
+        "(1,6): invalid-codepoint-in-foreign-content",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "�a"
+                      },
+                      {
+                        "tag": "frameset",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>�a<frameset></frameset></svg></body></html>",
+        "noQuirksBodyHtml": "<svg>�a<frameset></frameset></svg>"
+      }
+    },
+    {
+      "data": "<svg>\u0000</svg><frameset>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,6): invalid-codepoint",
+        "(1,6): invalid-codepoint-in-foreign-content",
+        "(1,22): unexpected-start-tag",
+        "(1,22): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<svg>�</svg>"
+      }
+    },
+    {
+      "data": "<svg>\u0000 </svg><frameset>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,6): invalid-codepoint",
+        "(1,6): invalid-codepoint-in-foreign-content",
+        "(1,23): unexpected-start-tag",
+        "(1,23): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<svg>� </svg>"
+      }
+    },
+    {
+      "data": "<svg>\u0000a</svg><frameset>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,6): invalid-codepoint",
+        "(1,6): invalid-codepoint-in-foreign-content",
+        "(1,23): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "�a"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>�a</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>�a</svg>"
+      }
+    },
+    {
+      "data": "<svg><path></path></svg><frameset>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,34): unexpected-start-tag",
+        "(1,34): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<svg><path></path></svg>"
+      }
+    },
+    {
+      "data": "<svg><p><frameset>",
+      "errors": [
+        "(1, 5) expected-doctype-but-got-start-tag",
+        "(1, 8) unexpected-html-element-in-foreign-content",
+        "(1, 18) unexpected-start-tag",
+        "(1, 18) eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<svg><p><frameset></frameset></p></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><pre>\r\n\r\nA</pre>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true,
+          "extraNL": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "\nA",
+                        "extraNL": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>\n\nA</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>\n\nA</pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><pre>\r\rA</pre>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true,
+          "extraNL": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "\nA",
+                        "extraNL": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>\n\nA</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>\n\nA</pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><pre>\rA</pre>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "A"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>A</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>A</pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><table><tr><td><math><mtext>\u0000a",
+      "errors": [
+        "(1,44): invalid-codepoint",
+        "(1,44): invalid-codepoint-in-body",
+        "(1,45): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "math math": true,
+            "math mtext": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "math",
+                                    "ns": "http://www.w3.org/1998/Math/MathML",
+                                    "children": [
+                                      {
+                                        "tag": "mtext",
+                                        "ns": "http://www.w3.org/1998/Math/MathML",
+                                        "children": [
+                                          {
+                                            "text": "a"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><math><mtext>a</mtext></math></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><math><mtext>a</mtext></math></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><table><tr><td><svg><foreignObject>\u0000a",
+      "errors": [
+        "(1,51): invalid-codepoint",
+        "(1,51): invalid-codepoint-in-body",
+        "(1,52): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg foreignObject": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "foreignObject",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "text": "a"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><svg><foreignObject>a</foreignObject></svg></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><svg><foreignObject>a</foreignObject></svg></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><math><mi>a\u0000b",
+      "errors": [
+        "(1,27): invalid-codepoint",
+        "(1,27): invalid-codepoint-in-body",
+        "(1,28): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "ab"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi>ab</mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><mi>ab</mi></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><math><mo>a\u0000b",
+      "errors": [
+        "(1,27): invalid-codepoint",
+        "(1,27): invalid-codepoint-in-body",
+        "(1,28): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mo": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mo",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "ab"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mo>ab</mo></math></body></html>",
+        "noQuirksBodyHtml": "<math><mo>ab</mo></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><math><mn>a\u0000b",
+      "errors": [
+        "(1,27): invalid-codepoint",
+        "(1,27): invalid-codepoint-in-body",
+        "(1,28): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mn": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mn",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "ab"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mn>ab</mn></math></body></html>",
+        "noQuirksBodyHtml": "<math><mn>ab</mn></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><math><ms>a\u0000b",
+      "errors": [
+        "(1,27): invalid-codepoint",
+        "(1,27): invalid-codepoint-in-body",
+        "(1,28): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math ms": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "ms",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "ab"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><ms>ab</ms></math></body></html>",
+        "noQuirksBodyHtml": "<math><ms>ab</ms></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><math><mtext>a\u0000b",
+      "errors": [
+        "(1,30): invalid-codepoint",
+        "(1,30): invalid-codepoint-in-body",
+        "(1,31): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mtext": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mtext",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "ab"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mtext>ab</mtext></math></body></html>",
+        "noQuirksBodyHtml": "<math><mtext>ab</mtext></math>"
+      }
+    }
+  ],
+  "ruby.dat": [
+    {
+      "data": "<html><ruby>a<rb>b<rb></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rb": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rb",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rb"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rb>b</rb><rb></rb></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rb>b</rb><rb></rb></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rb>b<rt></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rb": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rb",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rt"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rb>b</rb><rt></rt></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rb>b</rb><rt></rt></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rb>b<rtc></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rb": true,
+            "rtc": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rb",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rtc"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rb>b</rb><rtc></rtc></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rb>b</rb><rtc></rtc></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rb>b<rp></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rb": true,
+            "rp": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rb",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rp"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rb>b</rb><rp></rp></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rb>b</rb><rp></rp></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rb>b<span></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rb": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rb",
+                        "children": [
+                          {
+                            "text": "b"
+                          },
+                          {
+                            "tag": "span"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rb>b<span></span></rb></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rb>b<span></span></rb></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rt>b<rb></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rt": true,
+            "rb": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rt",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rb"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rt>b</rt><rb></rb></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rt>b</rt><rb></rb></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rt>b<rt></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rt",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rt"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rt>b</rt><rt></rt></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rt>b</rt><rt></rt></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rt>b<rtc></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rt": true,
+            "rtc": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rt",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rtc"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rt>b</rt><rtc></rtc></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rt>b</rt><rtc></rtc></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rt>b<rp></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rt": true,
+            "rp": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rt",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rp"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rt>b</rt><rp></rp></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rt>b</rt><rp></rp></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rt>b<span></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rt": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rt",
+                        "children": [
+                          {
+                            "text": "b"
+                          },
+                          {
+                            "tag": "span"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rt>b<span></span></rt></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rt>b<span></span></rt></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rtc>b<rb></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rtc": true,
+            "rb": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rtc",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rb"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rtc>b</rtc><rb></rb></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rtc>b</rtc><rb></rb></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rtc>b<rt>c<rt>d</ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rtc": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rtc",
+                        "children": [
+                          {
+                            "text": "b"
+                          },
+                          {
+                            "tag": "rt",
+                            "children": [
+                              {
+                                "text": "c"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "rt",
+                            "children": [
+                              {
+                                "text": "d"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rtc>b<rt>c</rt><rt>d</rt></rtc></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rtc>b<rt>c</rt><rt>d</rt></rtc></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rtc>b<rtc></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rtc": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rtc",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rtc"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rtc>b</rtc><rtc></rtc></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rtc>b</rtc><rtc></rtc></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rtc>b<rp></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rtc": true,
+            "rp": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rtc",
+                        "children": [
+                          {
+                            "text": "b"
+                          },
+                          {
+                            "tag": "rp"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rtc>b<rp></rp></rtc></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rtc>b<rp></rp></rtc></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rtc>b<span></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rtc": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rtc",
+                        "children": [
+                          {
+                            "text": "b"
+                          },
+                          {
+                            "tag": "span"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rtc>b<span></span></rtc></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rtc>b<span></span></rtc></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rp>b<rb></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rp": true,
+            "rb": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rp",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rb"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rp>b</rp><rb></rb></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rp>b</rp><rb></rb></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rp>b<rt></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rp": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rp",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rt"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rp>b</rp><rt></rt></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rp>b</rp><rt></rt></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rp>b<rtc></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rp": true,
+            "rtc": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rp",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rtc"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rp>b</rp><rtc></rtc></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rp>b</rp><rtc></rtc></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rp>b<rp></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rp": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rp",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rp"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rp>b</rp><rp></rp></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rp>b</rp><rp></rp></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rp>b<span></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rp": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rp",
+                        "children": [
+                          {
+                            "text": "b"
+                          },
+                          {
+                            "tag": "span"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rp>b<span></span></rp></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rp>b<span></span></rp></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby><rtc><ruby>a<rb>b<rt></ruby></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rtc": true,
+            "rb": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "rtc",
+                        "children": [
+                          {
+                            "tag": "ruby",
+                            "children": [
+                              {
+                                "text": "a"
+                              },
+                              {
+                                "tag": "rb",
+                                "children": [
+                                  {
+                                    "text": "b"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "rt"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby><rtc><ruby>a<rb>b</rb><rt></rt></ruby></rtc></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><rtc><ruby>a<rb>b</rb><rt></rt></ruby></rtc></ruby>"
+      }
+    }
+  ],
+  "scriptdata01.dat": [
+    {
+      "data": "FOO<script>'Hello'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'Hello'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'Hello'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'Hello'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script></script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script"
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script></script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script></script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script></script >BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script"
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script></script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script></script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script></script/>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,21): self-closing-flag-on-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script"
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script></script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script></script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script></script/ >BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,20): unexpected-character-after-solidus-in-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script"
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script></script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script></script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\"></scriptx>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,42): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "</scriptx>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\"></scriptx>BAR</script></body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\"></scriptx>BAR</script>"
+      }
+    },
+    {
+      "data": "FOO<script></script foo=\">\" dd>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,31): attributes-in-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script"
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script></script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script></script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<!'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<!-'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!-'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!-'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!-'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<!--'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!--'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!--'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!--'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<!---'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!---'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!---'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!---'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<!-->'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!-->'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!-->'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!-->'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<!-->'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!-->'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!-->'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!-->'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<!-- potato'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!-- potato'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!-- potato'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!-- potato'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script>'<!-- <sCrIpt'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!-- <sCrIpt'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!-- <sCrIpt'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt>'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,56): expected-script-data-but-got-eof",
+        "(1,56): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt>'</script>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt>'</script>BAR</script></body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt>'</script>BAR</script>"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt> -'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,58): expected-script-data-but-got-eof",
+        "(1,58): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt> -'</script>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt> -'</script>BAR</script></body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt> -'</script>BAR</script>"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt> --'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,59): expected-script-data-but-got-eof",
+        "(1,59): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt> --'</script>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt> --'</script>BAR</script></body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt> --'</script>BAR</script>"
+      }
+    },
+    {
+      "data": "FOO<script>'<!-- <sCrIpt> -->'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt> -->'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script>'<!-- <sCrIpt> -->'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script>'<!-- <sCrIpt> -->'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt> --!>'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,61): expected-script-data-but-got-eof",
+        "(1,61): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt> --!>'</script>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt> --!>'</script>BAR</script></body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt> --!>'</script>BAR</script>"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt> -- >'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,61): expected-script-data-but-got-eof",
+        "(1,61): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt> -- >'</script>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt> -- >'</script>BAR</script></body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt> -- >'</script>BAR</script>"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt '</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,56): expected-script-data-but-got-eof",
+        "(1,56): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt '</script>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt '</script>BAR</script></body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt '</script>BAR</script>"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt/'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars",
+        "(1,56): expected-script-data-but-got-eof",
+        "(1,56): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt/'</script>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt/'</script>BAR</script></body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt/'</script>BAR</script>"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt\\'</script>BAR",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt\\'",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "BAR"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt\\'</script>BAR</body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt\\'</script>BAR"
+      }
+    },
+    {
+      "data": "FOO<script type=\"text/plain\">'<!-- <sCrIpt/'</script>BAR</script>QUX",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/plain"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "'<!-- <sCrIpt/'</script>BAR",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "QUX"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script type=\"text/plain\">'<!-- <sCrIpt/'</script>BAR</script>QUX</body></html>",
+        "noQuirksBodyHtml": "FOO<script type=\"text/plain\">'<!-- <sCrIpt/'</script>BAR</script>QUX"
+      }
+    },
+    {
+      "data": "FOO<script><!--<script>-></script>--></script>QUX",
+      "errors": [
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "FOO"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script>-></script>-->",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "QUX"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>FOO<script><!--<script>-></script>--></script>QUX</body></html>",
+        "noQuirksBodyHtml": "FOO<script><!--<script>-></script>--></script>QUX"
+      }
+    }
+  ],
+  "tables01.dat": [
+    {
+      "data": "<table><th>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,11): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "th": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "th"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><th></th></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><th></th></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><td>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,11): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><col foo='bar'>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,22): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true,
+            "col": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "col",
+                            "attrs": [
+                              {
+                                "name": "foo",
+                                "value": "bar"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup><col foo=\"bar\"></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup><col foo=\"bar\"></colgroup></table>"
+      }
+    },
+    {
+      "data": "<table><colgroup></html>foo",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,24): unexpected-end-tag",
+        "(1,27): foster-parenting-character-in-table",
+        "(1,27): foster-parenting-character-in-table",
+        "(1,27): foster-parenting-character-in-table",
+        "(1,27): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "foo"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>foo<table><colgroup></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "foo<table><colgroup></colgroup></table>"
+      }
+    },
+    {
+      "data": "<table></table><p>foo",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table></table><p>foo</p></body></html>",
+        "noQuirksBodyHtml": "<table></table><p>foo</p>"
+      }
+    },
+    {
+      "data": "<table></body></caption></col></colgroup></html></tbody></td></tfoot></th></thead></tr><td>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-end-tag",
+        "(1,24): unexpected-end-tag",
+        "(1,30): unexpected-end-tag",
+        "(1,41): unexpected-end-tag",
+        "(1,48): unexpected-end-tag",
+        "(1,56): unexpected-end-tag",
+        "(1,61): unexpected-end-tag",
+        "(1,69): unexpected-end-tag",
+        "(1,74): unexpected-end-tag",
+        "(1,82): unexpected-end-tag",
+        "(1,87): unexpected-end-tag",
+        "(1,91): unexpected-cell-in-table-body",
+        "(1,91): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><select><option>3</select></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,15): unexpected-start-tag-implies-table-voodoo"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option",
+                        "children": [
+                          {
+                            "text": "3"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><option>3</option></select><table></table></body></html>",
+        "noQuirksBodyHtml": "<select><option>3</option></select><table></table>"
+      }
+    },
+    {
+      "data": "<table><select><table></table></select></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,15): unexpected-start-tag-implies-table-voodoo",
+        "(1,22): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,22): unexpected-start-tag-implies-end-tag",
+        "(1,39): unexpected-end-tag",
+        "(1,47): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  },
+                  {
+                    "tag": "table"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select></select><table></table><table></table></body></html>",
+        "noQuirksBodyHtml": "<select></select><table></table><table></table>"
+      }
+    },
+    {
+      "data": "<table><select></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,15): unexpected-start-tag-implies-table-voodoo",
+        "(1,23): unexpected-table-element-end-tag-in-select-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select></select><table></table></body></html>",
+        "noQuirksBodyHtml": "<select></select><table></table>"
+      }
+    },
+    {
+      "data": "<table><select><option>A<tr><td>B</td></tr></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,15): unexpected-start-tag-implies-table-voodoo",
+        "(1,28): unexpected-table-element-start-tag-in-select-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option",
+                        "children": [
+                          {
+                            "text": "A"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "B"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><option>A</option></select><table><tbody><tr><td>B</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<select><option>A</option></select><table><tbody><tr><td>B</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><td></body></caption></col></colgroup></html>foo",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,18): unexpected-end-tag",
+        "(1,28): unexpected-end-tag",
+        "(1,34): unexpected-end-tag",
+        "(1,45): unexpected-end-tag",
+        "(1,52): unexpected-end-tag",
+        "(1,55): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "foo"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td>foo</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td>foo</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><td>A</table>B",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "A"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "B"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td>A</td></tr></tbody></table>B</body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td>A</td></tr></tbody></table>B"
+      }
+    },
+    {
+      "data": "<table><tr><caption>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "caption": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "caption"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr></tr></tbody><caption></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr></tr></tbody><caption></caption></table>"
+      }
+    },
+    {
+      "data": "<table><tr></body></caption></col></colgroup></html></td></th><td>foo",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,18): unexpected-end-tag-in-table-row",
+        "(1,28): unexpected-end-tag-in-table-row",
+        "(1,34): unexpected-end-tag-in-table-row",
+        "(1,45): unexpected-end-tag-in-table-row",
+        "(1,52): unexpected-end-tag-in-table-row",
+        "(1,57): unexpected-end-tag-in-table-row",
+        "(1,62): unexpected-end-tag-in-table-row",
+        "(1,69): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "foo"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td>foo</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td>foo</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><td><tr>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,15): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td></td></tr><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td></td></tr><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><td><button><td>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,23): unexpected-cell-end-tag",
+        "(1,23): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "button": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "button"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td><button></button></td><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><button></button></td><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><tr><td><svg><desc><td>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,30): unexpected-cell-end-tag",
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg desc": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "desc",
+                                        "ns": "http://www.w3.org/2000/svg"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td><svg><desc></desc></svg></td><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><svg><desc></desc></svg></td><td></td></tr></tbody></table>"
+      }
+    }
+  ],
+  "template.dat": [
+    {
+      "data": "<body><template>Hello</template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "text": "Hello"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template>Hello</template></body></html>",
+        "noQuirksBodyHtml": "<template>Hello</template>"
+      }
+    },
+    {
+      "data": "<template>Hello</template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "text": "Hello"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template>Hello</template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template>Hello</template>"
+      }
+    },
+    {
+      "data": "<template></template><div></div>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true,
+            "div": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template></template></head><body><div></div></body></html>",
+        "noQuirksBodyHtml": "<template></template><div></div>"
+      }
+    },
+    {
+      "data": "<html><template>Hello</template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "text": "Hello"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template>Hello</template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template>Hello</template>"
+      }
+    },
+    {
+      "data": "<head><template><div></div></template></head>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "div": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><div></div></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><div></div></template>"
+      }
+    },
+    {
+      "data": "<div><template><div><span></template><b>",
+      "errors": [
+        " * (1,6) missing DOCTYPE",
+        " * (1,38) mismatched template end tag",
+        " * (1,41) unexpected end of file"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "template": true,
+            "span": true,
+            "b": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "div",
+                                "children": [
+                                  {
+                                    "tag": "span"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><template><div><span></span></div></template><b></b></div></body></html>",
+        "noQuirksBodyHtml": "<div><template><div><span></span></div></template><b></b></div>"
+      }
+    },
+    {
+      "data": "<div><template></div>Hello",
+      "errors": [
+        " * (1,6) missing DOCTYPE",
+        " * (1,22) unexpected token in template",
+        " * (1,27) unexpected end of file in template",
+        " * (1,27) unexpected end of file"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "text": "Hello"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><template>Hello</template></div></body></html>",
+        "noQuirksBodyHtml": "<div><template>Hello</template></div>"
+      }
+    },
+    {
+      "data": "<div></template></div>",
+      "errors": [
+        " * (1,6) missing DOCTYPE",
+        " * (1,17) unexpected template end tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div></div></body></html>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<table><template></template></table>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template></template></table>"
+      }
+    },
+    {
+      "data": "<table><template></template></div>",
+      "errors": [
+        " * (1,8) missing DOCTYPE",
+        " * (1,35) unexpected token in table - foster parenting",
+        " * (1,35) unexpected end tag",
+        " * (1,35) unexpected end of file"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template></template></table>"
+      }
+    },
+    {
+      "data": "<table><div><template></template></div>",
+      "errors": [
+        " * (1,8) missing DOCTYPE",
+        " * (1,13) unexpected token in table - foster parenting",
+        " * (1,40) unexpected token in table - foster parenting",
+        " * (1,40) unexpected end of file"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "template": true,
+            "table": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><template></template></div><table></table></body></html>",
+        "noQuirksBodyHtml": "<div><template></template></div><table></table>"
+      }
+    },
+    {
+      "data": "<table><template></template><div></div>",
+      "errors": [
+        "no doctype",
+        "bad div in table",
+        "bad /div in table",
+        "eof in table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "table": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div></div><table><template></template></table></body></html>",
+        "noQuirksBodyHtml": "<div></div><table><template></template></table>"
+      }
+    },
+    {
+      "data": "<table>   <template></template></table>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "text": "   "
+                      },
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table>   <template></template></table></body></html>",
+        "noQuirksBodyHtml": "<table>   <template></template></table>"
+      }
+    },
+    {
+      "data": "<table><tbody><template></template></tbody>",
+      "errors": [
+        "no doctype",
+        "eof in table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><template></template></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><template></template></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><tbody><template></tbody></template>",
+      "errors": [
+        "no doctype",
+        "bad /tbody",
+        "eof in table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><template></template></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><template></template></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><tbody><template></template></tbody></table>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><template></template></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><template></template></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><thead><template></template></thead>",
+      "errors": [
+        "no doctype",
+        "eof in table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "thead": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "thead",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><thead><template></template></thead></table></body></html>",
+        "noQuirksBodyHtml": "<table><thead><template></template></thead></table>"
+      }
+    },
+    {
+      "data": "<table><tfoot><template></template></tfoot>",
+      "errors": [
+        "no doctype",
+        "eof in table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tfoot": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tfoot",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tfoot><template></template></tfoot></table></body></html>",
+        "noQuirksBodyHtml": "<table><tfoot><template></template></tfoot></table>"
+      }
+    },
+    {
+      "data": "<select><template></template></select>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><template></template></select></body></html>",
+        "noQuirksBodyHtml": "<select><template></template></select>"
+      }
+    },
+    {
+      "data": "<select><template><option></option></template></select>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "template": true,
+            "option": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "option"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><template><option></option></template></select></body></html>",
+        "noQuirksBodyHtml": "<select><template><option></option></template></select>"
+      }
+    },
+    {
+      "data": "<template><option></option></select><option></option></template>",
+      "errors": [
+        "no doctype",
+        "bad /select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "option": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "option"
+                          },
+                          {
+                            "tag": "option"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><option></option><option></option></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><option></option><option></option></template>"
+      }
+    },
+    {
+      "data": "<select><template></template><option></select>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "template": true,
+            "option": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><template></template><option></option></select></body></html>",
+        "noQuirksBodyHtml": "<select><template></template><option></option></select>"
+      }
+    },
+    {
+      "data": "<select><option><template></template></select>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><option><template></template></option></select></body></html>",
+        "noQuirksBodyHtml": "<select><option><template></template></option></select>"
+      }
+    },
+    {
+      "data": "<select><template>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><template></template></select></body></html>",
+        "noQuirksBodyHtml": "<select><template></template></select>"
+      }
+    },
+    {
+      "data": "<select><option></option><template>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      },
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><option></option><template></template></select></body></html>",
+        "noQuirksBodyHtml": "<select><option></option><template></template></select>"
+      }
+    },
+    {
+      "data": "<select><option></option><template><option>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      },
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "option"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><option></option><template><option></option></template></select></body></html>",
+        "noQuirksBodyHtml": "<select><option></option><template><option></option></template></select>"
+      }
+    },
+    {
+      "data": "<table><thead><template><td></template></table>",
+      "errors": [
+        " * (1,8) missing DOCTYPE"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "thead": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "thead",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "td"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><thead><template><td></td></template></thead></table></body></html>",
+        "noQuirksBodyHtml": "<table><thead><template><td></td></template></thead></table>"
+      }
+    },
+    {
+      "data": "<table><template><thead></template></table>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true,
+            "thead": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "thead"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template><thead></thead></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template><thead></thead></template></table>"
+      }
+    },
+    {
+      "data": "<body><table><template><td></tr><div></template></table>",
+      "errors": [
+        "no doctype",
+        "bad </tr>",
+        "missing </div>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true,
+            "td": true,
+            "div": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "div"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template><td><div></div></td></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template><td><div></div></td></template></table>"
+      }
+    },
+    {
+      "data": "<table><template><thead></template></thead></table>",
+      "errors": [
+        "no doctype",
+        "bad /thead after /template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true,
+            "thead": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "thead"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template><thead></thead></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template><thead></thead></template></table>"
+      }
+    },
+    {
+      "data": "<table><thead><template><tr></template></table>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "thead": true,
+            "template": true,
+            "tr": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "thead",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "tr"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><thead><template><tr></tr></template></thead></table></body></html>",
+        "noQuirksBodyHtml": "<table><thead><template><tr></tr></template></thead></table>"
+      }
+    },
+    {
+      "data": "<table><template><tr></template></table>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true,
+            "tr": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "tr"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template><tr></tr></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template><tr></tr></template></table>"
+      }
+    },
+    {
+      "data": "<table><tr><template><td>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "template",
+                                "children": [
+                                  {
+                                    "content": true,
+                                    "children": [
+                                      {
+                                        "tag": "td"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><template><td></td></template></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><template><td></td></template></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><template><tr><template><td></template></tr></template></table>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true,
+            "tr": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "template",
+                                    "children": [
+                                      {
+                                        "content": true,
+                                        "children": [
+                                          {
+                                            "tag": "td"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template><tr><template><td></td></template></tr></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template><tr><template><td></td></template></tr></template></table>"
+      }
+    },
+    {
+      "data": "<table><template><tr><template><td></td></template></tr></template></table>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true,
+            "tr": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "template",
+                                    "children": [
+                                      {
+                                        "content": true,
+                                        "children": [
+                                          {
+                                            "tag": "td"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template><tr><template><td></td></template></tr></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template><tr><template><td></td></template></tr></template></table>"
+      }
+    },
+    {
+      "data": "<table><template><td></template>",
+      "errors": [
+        "no doctype",
+        "eof in table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><template><td></td></template></table></body></html>",
+        "noQuirksBodyHtml": "<table><template><td></td></template></table>"
+      }
+    },
+    {
+      "data": "<body><template><td></td></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><template><tr></tr></template><td></td></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "tr": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "tr"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><template><tr></tr></template><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><template><tr></tr></template><td></td></template>"
+      }
+    },
+    {
+      "data": "<table><colgroup><template><col>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true,
+            "template": true,
+            "col": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "col"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup><template><col></template></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup><template><col></template></colgroup></table>"
+      }
+    },
+    {
+      "data": "<frameset><template><frame></frame></template></frameset>",
+      "errors": [
+        " * (1,11) missing DOCTYPE",
+        " * (1,21) unexpected start tag token",
+        " * (1,36) unexpected end tag token",
+        " * (1,47) unexpected end tag token"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset><frame></frameset></html>",
+        "noQuirksBodyHtml": "<template></template>"
+      }
+    },
+    {
+      "data": "<template><frame></frame></frameset><frame></frame></template>",
+      "errors": [
+        " * (1,11) missing DOCTYPE",
+        " * (1,18) unexpected start tag",
+        " * (1,26) unexpected end tag",
+        " * (1,37) unexpected end tag",
+        " * (1,44) unexpected start tag",
+        " * (1,52) unexpected end tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template></template>"
+      }
+    },
+    {
+      "data": "<template><div><frameset><span></span></div><span></span></template>",
+      "errors": [
+        "no doctype",
+        "bad frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "div": true,
+            "span": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "tag": "span"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "span"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><div><span></span></div><span></span></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><div><span></span></div><span></span></template>"
+      }
+    },
+    {
+      "data": "<body><template><div><frameset><span></span></div><span></span></template></body>",
+      "errors": [
+        "no doctype",
+        "bad frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "div": true,
+            "span": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "tag": "span"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "span"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><div><span></span></div><span></span></template></body></html>",
+        "noQuirksBodyHtml": "<template><div><span></span></div><span></span></template>"
+      }
+    },
+    {
+      "data": "<body><template><script>var i = 1;</script><td></td></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "script": true,
+            "td": true
+          },
+          "template": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "script",
+                            "children": [
+                              {
+                                "text": "var i = 1;",
+                                "no_escape": true
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><script>var i = 1;</script><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><script>var i = 1;</script><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><tr><div></div></tr></template>",
+      "errors": [
+        "no doctype",
+        "foster-parented div",
+        "foster-parented /div"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "tr": true,
+            "div": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "tr"
+                          },
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><tr></tr><div></div></template></body></html>",
+        "noQuirksBodyHtml": "<template><tr></tr><div></div></template>"
+      }
+    },
+    {
+      "data": "<body><template><tr></tr><td></td></template>",
+      "errors": [
+        "no doctype",
+        "unexpected <td>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "tr": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "tr"
+                          },
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><tr></tr><tr><td></td></tr></template></body></html>",
+        "noQuirksBodyHtml": "<template><tr></tr><tr><td></td></tr></template>"
+      }
+    },
+    {
+      "data": "<body><template><td></td></tr><td></td></template>",
+      "errors": [
+        "no doctype",
+        "bad </tr>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "td"
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><td></td><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><td></td><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><td></td><tbody><td></td></template>",
+      "errors": [
+        "no doctype",
+        "bad <tbody>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "td"
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><td></td><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><td></td><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><td></td><caption></caption><td></td></template>",
+      "errors": [
+        " * (1,7) missing DOCTYPE",
+        " * (1,35) unexpected start tag in table row",
+        " * (1,45) unexpected end tag in table row"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "td"
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><td></td><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><td></td><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><td></td><colgroup></caption><td></td></template>",
+      "errors": [
+        " * (1,7) missing DOCTYPE",
+        " * (1,36) unexpected start tag in table row",
+        " * (1,46) unexpected end tag in table row"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "td"
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><td></td><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><td></td><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><td></td></table><td></td></template>",
+      "errors": [
+        "no doctype",
+        "bad </table>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "td"
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><td></td><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><td></td><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><tr></tr><tbody><tr></tr></template>",
+      "errors": [
+        "no doctype",
+        "bad <tbody>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "tr": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "tr"
+                          },
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><tr></tr><tr></tr></template></body></html>",
+        "noQuirksBodyHtml": "<template><tr></tr><tr></tr></template>"
+      }
+    },
+    {
+      "data": "<body><template><tr></tr><caption><tr></tr></template>",
+      "errors": [
+        "no doctype",
+        "bad <caption>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "tr": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "tr"
+                          },
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><tr></tr><tr></tr></template></body></html>",
+        "noQuirksBodyHtml": "<template><tr></tr><tr></tr></template>"
+      }
+    },
+    {
+      "data": "<body><template><tr></tr></table><tr></tr></template>",
+      "errors": [
+        "no doctype",
+        "bad </table>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "tr": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "tr"
+                          },
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><tr></tr><tr></tr></template></body></html>",
+        "noQuirksBodyHtml": "<template><tr></tr><tr></tr></template>"
+      }
+    },
+    {
+      "data": "<body><template><thead></thead><caption></caption><tbody></tbody></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "thead": true,
+            "caption": true,
+            "tbody": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "thead"
+                          },
+                          {
+                            "tag": "caption"
+                          },
+                          {
+                            "tag": "tbody"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><thead></thead><caption></caption><tbody></tbody></template></body></html>",
+        "noQuirksBodyHtml": "<template><thead></thead><caption></caption><tbody></tbody></template>"
+      }
+    },
+    {
+      "data": "<body><template><thead></thead></table><tbody></tbody></template></body>",
+      "errors": [
+        "no doctype",
+        "bad </table>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "thead": true,
+            "tbody": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "thead"
+                          },
+                          {
+                            "tag": "tbody"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><thead></thead><tbody></tbody></template></body></html>",
+        "noQuirksBodyHtml": "<template><thead></thead><tbody></tbody></template>"
+      }
+    },
+    {
+      "data": "<body><template><div><tr></tr></div></template>",
+      "errors": [
+        "no doctype",
+        "bad tr",
+        "bad /tr"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "div": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><div></div></template></body></html>",
+        "noQuirksBodyHtml": "<template><div></div></template>"
+      }
+    },
+    {
+      "data": "<body><template><em>Hello</em></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "em": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "em",
+                            "children": [
+                              {
+                                "text": "Hello"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><em>Hello</em></template></body></html>",
+        "noQuirksBodyHtml": "<template><em>Hello</em></template>"
+      }
+    },
+    {
+      "data": "<body><template><!--comment--></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true
+          },
+          "template": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "comment": "comment"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><!--comment--></template></body></html>",
+        "noQuirksBodyHtml": "<template><!--comment--></template>"
+      }
+    },
+    {
+      "data": "<body><template><style></style><td></td></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "style": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "style"
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><style></style><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><style></style><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><meta><td></td></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "meta": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "meta"
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><meta><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><meta><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><link><td></td></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "link": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "link"
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><link><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><link><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><template><template><tr></tr></template><td></td></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "tr": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "tr"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><template><tr></tr></template><td></td></template></body></html>",
+        "noQuirksBodyHtml": "<template><template><tr></tr></template><td></td></template>"
+      }
+    },
+    {
+      "data": "<body><table><colgroup><template><col></col></template></colgroup></table></body>",
+      "errors": [
+        "no doctype",
+        "bad /col"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true,
+            "template": true,
+            "col": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "col"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup><template><col></template></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup><template><col></template></colgroup></table>"
+      }
+    },
+    {
+      "data": "<body a=b><template><div></div><body c=d><div></div></body></template></body>",
+      "errors": [
+        "no doctype",
+        "bad <body>",
+        "bad </body>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "div": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "a",
+                    "value": "b"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "div"
+                          },
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body a=\"b\"><template><div></div><div></div></template></body></html>",
+        "noQuirksBodyHtml": "<template><div></div><div></div></template>"
+      }
+    },
+    {
+      "data": "<html a=b><template><div><html b=c><span></template>",
+      "errors": [
+        "no doctype",
+        "bad <html>",
+        "missing end tags in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "div": true,
+            "span": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "a",
+                "value": "b"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "tag": "span"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html a=\"b\"><head><template><div><span></span></div></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><div><span></span></div></template>"
+      }
+    },
+    {
+      "data": "<html a=b><template><col></col><html b=c><col></col></template>",
+      "errors": [
+        "no doctype",
+        "bad /col",
+        "bad html",
+        "bad /col"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "col": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "a",
+                "value": "b"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "col"
+                          },
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html a=\"b\"><head><template><col><col></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><col><col></template>"
+      }
+    },
+    {
+      "data": "<html a=b><template><frame></frame><html b=c><frame></frame></template>",
+      "errors": [
+        "no doctype",
+        "bad frame",
+        "bad /frame",
+        "bad html",
+        "bad frame",
+        "bad /frame"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "a",
+                "value": "b"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html a=\"b\"><head><template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template></template>"
+      }
+    },
+    {
+      "data": "<body><template><tr></tr><template></template><td></td></template>",
+      "errors": [
+        "no doctype",
+        "unexpected <td>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "tr": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "tr"
+                          },
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><tr></tr><template></template><tr><td></td></tr></template></body></html>",
+        "noQuirksBodyHtml": "<template><tr></tr><template></template><tr><td></td></tr></template>"
+      }
+    },
+    {
+      "data": "<body><template><thead></thead><template><tr></tr></template><tr></tr><tfoot></tfoot></template>",
+      "errors": [
+        "no doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "thead": true,
+            "tr": true,
+            "tbody": true,
+            "tfoot": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "thead"
+                          },
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "tr"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "tfoot"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><thead></thead><template><tr></tr></template><tbody><tr></tr></tbody><tfoot></tfoot></template></body></html>",
+        "noQuirksBodyHtml": "<template><thead></thead><template><tr></tr></template><tbody><tr></tr></tbody><tfoot></tfoot></template>"
+      }
+    },
+    {
+      "data": "<body><template><template><b><template></template></template>text</template>",
+      "errors": [
+        "no doctype",
+        "missing </b>"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "b": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "b",
+                                    "children": [
+                                      {
+                                        "tag": "template",
+                                        "children": [
+                                          {
+                                            "content": true
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "text": "text"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><template><b><template></template></b></template>text</template></body></html>",
+        "noQuirksBodyHtml": "<template><template><b><template></template></b></template>text</template>"
+      }
+    },
+    {
+      "data": "<body><template><col><colgroup>",
+      "errors": [
+        "no doctype",
+        "bad colgroup",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "col": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><col></template></body></html>",
+        "noQuirksBodyHtml": "<template><col></template>"
+      }
+    },
+    {
+      "data": "<body><template><col></colgroup>",
+      "errors": [
+        "no doctype",
+        "bogus /colgroup",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "col": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><col></template></body></html>",
+        "noQuirksBodyHtml": "<template><col></template>"
+      }
+    },
+    {
+      "data": "<body><template><col><colgroup></template></body>",
+      "errors": [
+        "no doctype",
+        "bad colgroup"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "col": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><col></template></body></html>",
+        "noQuirksBodyHtml": "<template><col></template>"
+      }
+    },
+    {
+      "data": "<body><template><col><div>",
+      "errors": [
+        " * (1,7) missing DOCTYPE",
+        " * (1,27) unexpected token",
+        " * (1,27) unexpected end of file in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "col": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><col></template></body></html>",
+        "noQuirksBodyHtml": "<template><col></template>"
+      }
+    },
+    {
+      "data": "<body><template><col></div>",
+      "errors": [
+        "no doctype",
+        "bad /div",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "col": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><col></template></body></html>",
+        "noQuirksBodyHtml": "<template><col></template>"
+      }
+    },
+    {
+      "data": "<body><template><col>Hello",
+      "errors": [
+        "no doctype",
+        "unexpected text",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "col": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><col></template></body></html>",
+        "noQuirksBodyHtml": "<template><col></template>"
+      }
+    },
+    {
+      "data": "<body><template><i><menu>Foo</i>",
+      "errors": [
+        "no doctype",
+        "mising /menu",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "i": true,
+            "menu": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "i"
+                          },
+                          {
+                            "tag": "menu",
+                            "children": [
+                              {
+                                "tag": "i",
+                                "children": [
+                                  {
+                                    "text": "Foo"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><i></i><menu><i>Foo</i></menu></template></body></html>",
+        "noQuirksBodyHtml": "<template><i></i><menu><i>Foo</i></menu></template>"
+      }
+    },
+    {
+      "data": "<body><template></div><div>Foo</div><template></template><tr></tr>",
+      "errors": [
+        "no doctype",
+        "bogus /div",
+        "bogus tr",
+        "bogus /tr",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true,
+            "div": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "text": "Foo"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template><div>Foo</div><template></template></template></body></html>",
+        "noQuirksBodyHtml": "<template><div>Foo</div><template></template></template>"
+      }
+    },
+    {
+      "data": "<body><div><template></div><tr><td>Foo</td></tr></template>",
+      "errors": [
+        " * (1,7) missing DOCTYPE",
+        " * (1,28) unexpected token in template",
+        " * (1,60) unexpected end of file"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "template": true,
+            "tr": true,
+            "td": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "text": "Foo"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><template><tr><td>Foo</td></tr></template></div></body></html>",
+        "noQuirksBodyHtml": "<div><template><tr><td>Foo</td></tr></template></div>"
+      }
+    },
+    {
+      "data": "<template></figcaption><sub><table></table>",
+      "errors": [
+        "no doctype",
+        "bad /figcaption",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "sub": true,
+            "table": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "sub",
+                            "children": [
+                              {
+                                "tag": "table"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><sub><table></table></sub></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><sub><table></table></sub></template>"
+      }
+    },
+    {
+      "data": "<template><template>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template></template></template>"
+      }
+    },
+    {
+      "data": "<template><div>",
+      "errors": [
+        "no doctype",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "div": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><div></div></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><div></div></template>"
+      }
+    },
+    {
+      "data": "<template><template><div>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "div": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "div"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><div></div></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><div></div></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><table>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "table": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "table"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><table></table></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><table></table></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><tbody>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "tbody": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "tbody"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><tbody></tbody></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><tbody></tbody></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><tr>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "tr": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "tr"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><tr></tr></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><tr></tr></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><td>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "td": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "td"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><td></td></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><td></td></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><caption>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "caption": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "caption"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><caption></caption></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><caption></caption></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><colgroup>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "colgroup": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "colgroup"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><colgroup></colgroup></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><colgroup></colgroup></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><col>",
+      "errors": [
+        "no doctype",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "col": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "col"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><col></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><col></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><tbody><select>",
+      "errors": [
+        " * (1,11) missing DOCTYPE",
+        " * (1,36) unexpected token in table - foster parenting",
+        " * (1,36) unexpected end of file in template",
+        " * (1,36) unexpected end of file in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "tbody": true,
+            "select": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "tbody"
+                                  },
+                                  {
+                                    "tag": "select"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><tbody></tbody><select></select></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><tbody></tbody><select></select></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><table>Foo",
+      "errors": [
+        "no doctype",
+        "foster-parenting text F",
+        "foster-parenting text o",
+        "foster-parenting text o",
+        "eof",
+        "eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "table": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "text": "Foo"
+                                  },
+                                  {
+                                    "tag": "table"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template>Foo<table></table></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template>Foo<table></table></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><frame>",
+      "errors": [
+        "no doctype",
+        "bad tag",
+        "eof",
+        "eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><script>var i",
+      "errors": [
+        "no doctype",
+        "eof in script",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "script": true,
+            "body": true
+          },
+          "template": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "script",
+                                    "children": [
+                                      {
+                                        "text": "var i",
+                                        "no_escape": true
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><script>var i</script></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><script>var i</script></template></template>"
+      }
+    },
+    {
+      "data": "<template><template><style>var i",
+      "errors": [
+        "no doctype",
+        "eof in style",
+        "eof in template",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "style": true,
+            "body": true
+          },
+          "template": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "style",
+                                    "children": [
+                                      {
+                                        "text": "var i",
+                                        "no_escape": true
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><template><style>var i</style></template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><template><style>var i</style></template></template>"
+      }
+    },
+    {
+      "data": "<template><table></template><body><span>Foo",
+      "errors": [
+        "no doctype",
+        "missing /table",
+        "bad eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "table": true,
+            "body": true,
+            "span": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "table"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "span",
+                    "children": [
+                      {
+                        "text": "Foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><table></table></template></head><body><span>Foo</span></body></html>",
+        "noQuirksBodyHtml": "<template><table></table></template><span>Foo</span>"
+      }
+    },
+    {
+      "data": "<template><td></template><body><span>Foo",
+      "errors": [
+        "no doctype",
+        "bad eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "td": true,
+            "body": true,
+            "span": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "td"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "span",
+                    "children": [
+                      {
+                        "text": "Foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><td></td></template></head><body><span>Foo</span></body></html>",
+        "noQuirksBodyHtml": "<template><td></td></template><span>Foo</span>"
+      }
+    },
+    {
+      "data": "<template><object></template><body><span>Foo",
+      "errors": [
+        "no doctype",
+        "missing /object",
+        "bad eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "object": true,
+            "body": true,
+            "span": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "object"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "span",
+                    "children": [
+                      {
+                        "text": "Foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><object></object></template></head><body><span>Foo</span></body></html>",
+        "noQuirksBodyHtml": "<template><object></object></template><span>Foo</span>"
+      }
+    },
+    {
+      "data": "<template><svg><template>",
+      "errors": [
+        "no doctype",
+        "eof in template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "svg svg": true,
+            "svg template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "template",
+                                "ns": "http://www.w3.org/2000/svg"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><svg><template></template></svg></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><svg><template></template></svg></template>"
+      }
+    },
+    {
+      "data": "<template><svg><foo><template><foreignObject><div></template><div>",
+      "errors": [
+        "no doctype",
+        "ugly template closure",
+        "bad eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "svg svg": true,
+            "svg foo": true,
+            "svg template": true,
+            "svg foreignObject": true,
+            "div": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "foo",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "template",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "foreignObject",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "tag": "div"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><svg><foo><template><foreignObject><div></div></foreignObject></template></foo></svg></template></head><body><div></div></body></html>",
+        "noQuirksBodyHtml": "<template><svg><foo><template><foreignObject><div></div></foreignObject></template></foo></svg></template><div></div>"
+      }
+    },
+    {
+      "data": "<dummy><template><span></dummy>",
+      "errors": [
+        "no doctype",
+        "bad end tag </dummy>",
+        "eof in template",
+        "eof in dummy"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dummy": true,
+            "template": true,
+            "span": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dummy",
+                    "children": [
+                      {
+                        "tag": "template",
+                        "children": [
+                          {
+                            "content": true,
+                            "children": [
+                              {
+                                "tag": "span"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><dummy><template><span></span></template></dummy></body></html>",
+        "noQuirksBodyHtml": "<dummy><template><span></span></template></dummy>"
+      }
+    },
+    {
+      "data": "<body><table><tr><td><select><template>Foo</template><caption>A</table>",
+      "errors": [
+        "no doctype",
+        "(1,62): unexpected-caption-in-select-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "select": true,
+            "template": true,
+            "caption": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "select",
+                                    "children": [
+                                      {
+                                        "tag": "template",
+                                        "children": [
+                                          {
+                                            "content": true,
+                                            "children": [
+                                              {
+                                                "text": "Foo"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "text": "A"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td><select><template>Foo</template></select></td></tr></tbody><caption>A</caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><select><template>Foo</template></select></td></tr></tbody><caption>A</caption></table>"
+      }
+    },
+    {
+      "data": "<body></body><template>",
+      "errors": [
+        "no doctype",
+        "(1,23): template-after-body",
+        "(1,24): eof-in-template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "template": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><template></template></body></html>",
+        "noQuirksBodyHtml": "<template></template>"
+      }
+    },
+    {
+      "data": "<head></head><template>",
+      "errors": [
+        "no doctype",
+        "(1,23): template-after-head",
+        "(1,24): eof-in-template"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template></template>"
+      }
+    },
+    {
+      "data": "<head></head><template>Foo</template>",
+      "errors": [
+        "no doctype",
+        "(1,23): template-after-head"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "text": "Foo"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template>Foo</template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template>Foo</template>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE HTML><dummy><table><template><table><template><table><script>",
+      "errors": [
+        "eof script",
+        "eof template",
+        "eof template",
+        "eof table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dummy": true,
+            "table": true,
+            "template": true,
+            "script": true
+          },
+          "doctype": true,
+          "template": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dummy",
+                    "children": [
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "template",
+                            "children": [
+                              {
+                                "content": true,
+                                "children": [
+                                  {
+                                    "tag": "table",
+                                    "children": [
+                                      {
+                                        "tag": "template",
+                                        "children": [
+                                          {
+                                            "content": true,
+                                            "children": [
+                                              {
+                                                "tag": "table",
+                                                "children": [
+                                                  {
+                                                    "tag": "script"
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><dummy><table><template><table><template><table><script></script></table></template></table></template></table></dummy></body></html>",
+        "noQuirksBodyHtml": "<dummy><table><template><table><template><table><script></script></table></template></table></template></table></dummy>"
+      }
+    },
+    {
+      "data": "<template><a><table><a>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "template": true,
+            "a": true,
+            "table": true,
+            "body": true
+          },
+          "template": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "template",
+                    "children": [
+                      {
+                        "content": true,
+                        "children": [
+                          {
+                            "tag": "a",
+                            "children": [
+                              {
+                                "tag": "a"
+                              },
+                              {
+                                "tag": "table"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><template><a><a></a><table></table></a></template></head><body></body></html>",
+        "noQuirksBodyHtml": "<template><a><a></a><table></table></a></template>"
+      }
+    }
+  ],
+  "tests1.dat": [
+    {
+      "data": "Test",
+      "errors": [
+        "(1,0): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Test"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>Test</body></html>",
+        "noQuirksBodyHtml": "Test"
+      }
+    },
+    {
+      "data": "<p>One<p>Two",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "One"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "Two"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p>One</p><p>Two</p></body></html>",
+        "noQuirksBodyHtml": "<p>One</p><p>Two</p>"
+      }
+    },
+    {
+      "data": "Line1<br>Line2<br>Line3<br>Line4",
+      "errors": [
+        "(1,0): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "br": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Line1"
+                  },
+                  {
+                    "tag": "br"
+                  },
+                  {
+                    "text": "Line2"
+                  },
+                  {
+                    "tag": "br"
+                  },
+                  {
+                    "text": "Line3"
+                  },
+                  {
+                    "tag": "br"
+                  },
+                  {
+                    "text": "Line4"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>Line1<br>Line2<br>Line3<br>Line4</body></html>",
+        "noQuirksBodyHtml": "Line1<br>Line2<br>Line3<br>Line4"
+      }
+    },
+    {
+      "data": "<html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<head>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<body>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head></head>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head></head><body>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head></head><body></body>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head><body></body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head></body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><head><body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<head></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "</head>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "</body>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-end-tag element."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "</html>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-end-tag element."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<b><table><td><i></table>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-cell-in-table-body",
+        "(1,25): unexpected-cell-end-tag",
+        "(1,25): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "i": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "tag": "i"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><table><tbody><tr><td><i></i></td></tr></tbody></table></b></body></html>",
+        "noQuirksBodyHtml": "<b><table><tbody><tr><td><i></i></td></tr></tbody></table></b>"
+      }
+    },
+    {
+      "data": "<b><table><td></b><i></table>X",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-cell-in-table-body",
+        "(1,18): unexpected-end-tag",
+        "(1,29): unexpected-cell-end-tag",
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "i": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "tag": "i"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><table><tbody><tr><td><i></i></td></tr></tbody></table>X</b></body></html>",
+        "noQuirksBodyHtml": "<b><table><tbody><tr><td><i></i></td></tr></tbody></table>X</b>"
+      }
+    },
+    {
+      "data": "<h1>Hello<h2>World",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag",
+        "(1,13): unexpected-start-tag",
+        "(1,18): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "h1": true,
+            "h2": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "h1",
+                    "children": [
+                      {
+                        "text": "Hello"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "h2",
+                    "children": [
+                      {
+                        "text": "World"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><h1>Hello</h1><h2>World</h2></body></html>",
+        "noQuirksBodyHtml": "<h1>Hello</h1><h2>World</h2>"
+      }
+    },
+    {
+      "data": "<a><p>X<a>Y</a>Z</p></a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,10): unexpected-start-tag-implies-end-tag",
+        "(1,10): adoption-agency-1.3",
+        "(1,24): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "X"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "Y"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "Z"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a></a><p><a>X</a><a>Y</a>Z</p></body></html>",
+        "noQuirksBodyHtml": "<a></a><p><a>X</a><a>Y</a>Z</p>"
+      }
+    },
+    {
+      "data": "<b><button>foo</b>bar",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,18): adoption-agency-1.3",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "button": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "button",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "bar"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b></b><button><b>foo</b>bar</button></body></html>",
+        "noQuirksBodyHtml": "<b></b><button><b>foo</b>bar</button>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><span><button>foo</span>bar",
+      "errors": [
+        "(1,39): unexpected-end-tag",
+        "(1,42): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "span": true,
+            "button": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "span",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "text": "foobar"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><span><button>foobar</button></span></body></html>",
+        "noQuirksBodyHtml": "<span><button>foobar</button></span>"
+      }
+    },
+    {
+      "data": "<p><b><div><marquee></p></b></div>X",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-end-tag",
+        "(1,24): unexpected-end-tag",
+        "(1,28): unexpected-end-tag",
+        "(1,34): end-tag-too-early",
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "b": true,
+            "div": true,
+            "marquee": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "marquee",
+                            "children": [
+                              {
+                                "tag": "p"
+                              },
+                              {
+                                "text": "X"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><b></b></p><div><b><marquee><p></p>X</marquee></b></div></body></html>",
+        "noQuirksBodyHtml": "<p><b></b></p><div><b><marquee><p></p>X</marquee></b></div>"
+      }
+    },
+    {
+      "data": "<script><div></script></div><title><p></title><p><p>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,28): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "title": true,
+            "body": true,
+            "p": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<div>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<p>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><div></script><title>&lt;p&gt;</title></head><body><p></p><p></p></body></html>",
+        "noQuirksBodyHtml": "<script><div></script><title>&lt;p&gt;</title><p></p><p></p>"
+      }
+    },
+    {
+      "data": "<!--><div>--<!-->",
+      "errors": [
+        "(1,5): incorrect-comment",
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,17): incorrect-comment",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": ""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "--"
+                      },
+                      {
+                        "comment": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!----><html><head></head><body><div>--<!----></div></body></html>",
+        "noQuirksBodyHtml": "<!----><div>--<!----></div>"
+      }
+    },
+    {
+      "data": "<p><hr></p>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "hr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "hr"
+                  },
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p></p><hr><p></p></body></html>",
+        "noQuirksBodyHtml": "<p></p><hr><p></p>"
+      }
+    },
+    {
+      "data": "<select><b><option><select><option></b></select>X",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-start-tag-in-select",
+        "(1,27): unexpected-select-in-select",
+        "(1,39): unexpected-end-tag",
+        "(1,48): unexpected-end-tag",
+        "(1,49): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "option",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><option></option></select><option>X</option></body></html>",
+        "noQuirksBodyHtml": "<select><option></option></select><option>X</option>"
+      }
+    },
+    {
+      "data": "<a><table><td><a><table></table><a></tr><a></table><b>X</b>C<a>Y",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-cell-in-table-body",
+        "(1,35): unexpected-start-tag-implies-end-tag",
+        "(1,40): unexpected-cell-end-tag",
+        "(1,43): unexpected-start-tag-implies-table-voodoo",
+        "(1,43): unexpected-start-tag-implies-end-tag",
+        "(1,43): unexpected-end-tag",
+        "(1,63): unexpected-start-tag-implies-end-tag",
+        "(1,64): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "a"
+                      },
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "tag": "a",
+                                        "children": [
+                                          {
+                                            "tag": "table"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "a"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "X"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "C"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "Y"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><a></a><table><tbody><tr><td><a><table></table></a><a></a></td></tr></tbody></table></a><a><b>X</b>C</a><a>Y</a></body></html>",
+        "noQuirksBodyHtml": "<a><a></a><table><tbody><tr><td><a><table></table></a><a></a></td></tr></tbody></table></a><a><b>X</b>C</a><a>Y</a>"
+      }
+    },
+    {
+      "data": "<a X>0<b>1<a Y>2",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,15): unexpected-start-tag-implies-end-tag",
+        "(1,15): adoption-agency-1.3",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "x",
+                        "value": ""
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "0"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "1"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "attrs": [
+                          {
+                            "name": "y",
+                            "value": ""
+                          }
+                        ],
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a x=\"\">0<b>1</b></a><b><a y=\"\">2</a></b></body></html>",
+        "noQuirksBodyHtml": "<a x=\"\">0<b>1</b></a><b><a y=\"\">2</a></b>"
+      }
+    },
+    {
+      "data": "<!-----><font><div>hello<table>excite!<b>me!<th><i>please!</tr><!--X-->",
+      "errors": [
+        "(1,7): unexpected-dash-after-double-dash-in-comment",
+        "(1,14): expected-doctype-but-got-start-tag",
+        "(1,41): unexpected-start-tag-implies-table-voodoo",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): foster-parenting-character-in-table",
+        "(1,48): unexpected-cell-in-table-body",
+        "(1,63): unexpected-cell-end-tag",
+        "(1,71): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "font": true,
+            "div": true,
+            "b": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "th": true,
+            "i": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "-"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "font",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "text": "helloexcite!"
+                          },
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "text": "me!"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "table",
+                            "children": [
+                              {
+                                "tag": "tbody",
+                                "children": [
+                                  {
+                                    "tag": "tr",
+                                    "children": [
+                                      {
+                                        "tag": "th",
+                                        "children": [
+                                          {
+                                            "tag": "i",
+                                            "children": [
+                                              {
+                                                "text": "please!"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "comment": "X"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!-----><html><head></head><body><font><div>helloexcite!<b>me!</b><table><tbody><tr><th><i>please!</i></th></tr><!--X--></tbody></table></div></font></body></html>",
+        "noQuirksBodyHtml": "<!-----><font><div>helloexcite!<b>me!</b><table><tbody><tr><th><i>please!</i></th></tr><!--X--></tbody></table></div></font>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><li>hello<li>world<ul>how<li>do</ul>you</body><!--do-->",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "li": true,
+            "ul": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "li",
+                    "children": [
+                      {
+                        "text": "hello"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "li",
+                    "children": [
+                      {
+                        "text": "world"
+                      },
+                      {
+                        "tag": "ul",
+                        "children": [
+                          {
+                            "text": "how"
+                          },
+                          {
+                            "tag": "li",
+                            "children": [
+                              {
+                                "text": "do"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "text": "you"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "comment": "do"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><li>hello</li><li>world<ul>how<li>do</li></ul>you</li></body><!--do--></html>",
+        "noQuirksBodyHtml": "<li>hello</li><li>world<ul>how<li>do</li></ul>you<!--do--></li>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>A<option>B<optgroup>C<select>D</option>E",
+      "errors": [
+        "(1,54): unexpected-end-tag-in-select",
+        "(1,55): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "option": true,
+            "optgroup": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "A"
+                  },
+                  {
+                    "tag": "option",
+                    "children": [
+                      {
+                        "text": "B"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "optgroup",
+                    "children": [
+                      {
+                        "text": "C"
+                      },
+                      {
+                        "tag": "select",
+                        "children": [
+                          {
+                            "text": "DE"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>A<option>B</option><optgroup>C<select>DE</select></optgroup></body></html>",
+        "noQuirksBodyHtml": "A<option>B</option><optgroup>C<select>DE</select></optgroup>"
+      }
+    },
+    {
+      "data": "<",
+      "errors": [
+        "(1,1): expected-tag-name",
+        "(1,1): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "<",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&lt;</body></html>",
+        "noQuirksBodyHtml": "&lt;"
+      }
+    },
+    {
+      "data": "<#",
+      "errors": [
+        "(1,1): expected-tag-name",
+        "(1,1): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "<#",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&lt;#</body></html>",
+        "noQuirksBodyHtml": "&lt;#"
+      }
+    },
+    {
+      "data": "</",
+      "errors": [
+        "(1,2): expected-closing-tag-but-got-eof",
+        "(1,2): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "</",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&lt;/</body></html>",
+        "noQuirksBodyHtml": "&lt;/"
+      }
+    },
+    {
+      "data": "</#",
+      "errors": [
+        "(1,2): expected-closing-tag-but-got-char",
+        "(1,3): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "#"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--#--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--#-->"
+      }
+    },
+    {
+      "data": "<?",
+      "errors": [
+        "(1,1): expected-tag-name-but-got-question-mark",
+        "(1,2): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "?"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--?--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--?-->"
+      }
+    },
+    {
+      "data": "<?#",
+      "errors": [
+        "(1,1): expected-tag-name-but-got-question-mark",
+        "(1,3): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "?#"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--?#--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--?#-->"
+      }
+    },
+    {
+      "data": "<!",
+      "errors": [
+        "(1,2): expected-dashes-or-doctype",
+        "(1,2): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": ""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!----><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!---->"
+      }
+    },
+    {
+      "data": "<!#",
+      "errors": [
+        "(1,2): expected-dashes-or-doctype",
+        "(1,3): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "#"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--#--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--#-->"
+      }
+    },
+    {
+      "data": "<?COMMENT?>",
+      "errors": [
+        "(1,1): expected-tag-name-but-got-question-mark",
+        "(1,11): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "?COMMENT?"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--?COMMENT?--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--?COMMENT?-->"
+      }
+    },
+    {
+      "data": "<!COMMENT>",
+      "errors": [
+        "(1,2): expected-dashes-or-doctype",
+        "(1,10): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "COMMENT"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--COMMENT--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--COMMENT-->"
+      }
+    },
+    {
+      "data": "</ COMMENT >",
+      "errors": [
+        "(1,2): expected-closing-tag-but-got-char",
+        "(1,12): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": " COMMENT "
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!-- COMMENT --><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!-- COMMENT -->"
+      }
+    },
+    {
+      "data": "<?COM--MENT?>",
+      "errors": [
+        "(1,1): expected-tag-name-but-got-question-mark",
+        "(1,13): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "?COM--MENT?"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--?COM--MENT?--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--?COM--MENT?-->"
+      }
+    },
+    {
+      "data": "<!COM--MENT>",
+      "errors": [
+        "(1,2): expected-dashes-or-doctype",
+        "(1,12): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "COM--MENT"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!--COM--MENT--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--COM--MENT-->"
+      }
+    },
+    {
+      "data": "</ COM--MENT >",
+      "errors": [
+        "(1,2): expected-closing-tag-but-got-char",
+        "(1,14): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": " COM--MENT "
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!-- COM--MENT --><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!-- COM--MENT -->"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><style> EOF",
+      "errors": [
+        "(1,26): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": " EOF",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style> EOF</style></head><body></body></html>",
+        "noQuirksBodyHtml": "<style> EOF</style>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><script> <!-- </script> --> </script> EOF",
+      "errors": [
+        "(1,52): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": " <!-- ",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": " "
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->  EOF",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script> <!-- </script> </head><body>--&gt;  EOF</body></html>",
+        "noQuirksBodyHtml": "<script> <!-- </script> --&gt;  EOF"
+      }
+    },
+    {
+      "data": "<b><p></b>TEST",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,10): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b"
+                      },
+                      {
+                        "text": "TEST"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b></b><p><b></b>TEST</p></body></html>",
+        "noQuirksBodyHtml": "<b></b><p><b></b>TEST</p>"
+      }
+    },
+    {
+      "data": "<p id=a><b><p id=b></b>TEST",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,19): unexpected-end-tag",
+        "(1,23): adoption-agency-1.2"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "attrs": [
+                      {
+                        "name": "id",
+                        "value": "a"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "attrs": [
+                      {
+                        "name": "id",
+                        "value": "b"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "TEST"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p id=\"a\"><b></b></p><p id=\"b\">TEST</p></body></html>",
+        "noQuirksBodyHtml": "<p id=\"a\"><b></b></p><p id=\"b\">TEST</p>"
+      }
+    },
+    {
+      "data": "<b id=a><p><b id=b></p></b>TEST",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,23): unexpected-end-tag",
+        "(1,27): adoption-agency-1.2",
+        "(1,31): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "attrs": [
+                      {
+                        "name": "id",
+                        "value": "a"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "b"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "text": "TEST"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b id=\"a\"><p><b id=\"b\"></b></p>TEST</b></body></html>",
+        "noQuirksBodyHtml": "<b id=\"a\"><p><b id=\"b\"></b></p>TEST</b>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><title>U-test</title><body><div><p>Test<u></p></div></body>",
+      "errors": [
+        "(1,61): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true,
+            "div": true,
+            "p": true,
+            "u": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "U-test"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "Test"
+                          },
+                          {
+                            "tag": "u"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><title>U-test</title></head><body><div><p>Test<u></u></p></div></body></html>",
+        "noQuirksBodyHtml": "<title>U-test</title><div><p>Test<u></u></p></div>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><font><table></font></table></font>",
+      "errors": [
+        "(1,35): unexpected-end-tag-implies-table-voodoo",
+        "(1,35): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "font": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "font",
+                    "children": [
+                      {
+                        "tag": "table"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><font><table></table></font></body></html>",
+        "noQuirksBodyHtml": "<font><table></table></font>"
+      }
+    },
+    {
+      "data": "<font><p>hello<b>cruel</font>world",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,29): adoption-agency-1.3",
+        "(1,29): adoption-agency-1.3",
+        "(1,34): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "font": true,
+            "p": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "font"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "children": [
+                          {
+                            "text": "hello"
+                          },
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "text": "cruel"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "world"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><font></font><p><font>hello<b>cruel</b></font><b>world</b></p></body></html>",
+        "noQuirksBodyHtml": "<font></font><p><font>hello<b>cruel</b></font><b>world</b></p>"
+      }
+    },
+    {
+      "data": "<b>Test</i>Test",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-end-tag",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "TestTest"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b>TestTest</b></body></html>",
+        "noQuirksBodyHtml": "<b>TestTest</b>"
+      }
+    },
+    {
+      "data": "<b>A<cite>B<div>C",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "cite": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "A"
+                      },
+                      {
+                        "tag": "cite",
+                        "children": [
+                          {
+                            "text": "B"
+                          },
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "text": "C"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b>A<cite>B<div>C</div></cite></b></body></html>",
+        "noQuirksBodyHtml": "<b>A<cite>B<div>C</div></cite></b>"
+      }
+    },
+    {
+      "data": "<b>A<cite>B<div>C</cite>D",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,24): unexpected-end-tag",
+        "(1,25): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "cite": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "A"
+                      },
+                      {
+                        "tag": "cite",
+                        "children": [
+                          {
+                            "text": "B"
+                          },
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "text": "CD"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b>A<cite>B<div>CD</div></cite></b></body></html>",
+        "noQuirksBodyHtml": "<b>A<cite>B<div>CD</div></cite></b>"
+      }
+    },
+    {
+      "data": "<b>A<cite>B<div>C</b>D",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,21): adoption-agency-1.3",
+        "(1,22): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "cite": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "A"
+                      },
+                      {
+                        "tag": "cite",
+                        "children": [
+                          {
+                            "text": "B"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "C"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "D"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b>A<cite>B</cite></b><div><b>C</b>D</div></body></html>",
+        "noQuirksBodyHtml": "<b>A<cite>B</cite></b><div><b>C</b>D</div>"
+      }
+    },
+    {
+      "data": "",
+      "errors": [
+        "(1,0): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<DIV>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,5): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div></div></body></html>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,9): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc</div></body></html>",
+        "noQuirksBodyHtml": "<div> abc</div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,13): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b></b></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b></b></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def</b></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def</b></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i></i></b></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i></i></b></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,25): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi</i></b></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi</i></b></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi <P>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,29): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi "
+                              },
+                              {
+                                "tag": "p"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi <p></p></i></b></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi <p></p></i></b></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi <P> jkl",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi "
+                              },
+                              {
+                                "tag": "p",
+                                "children": [
+                                  {
+                                    "text": " jkl"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi <p> jkl</p></i></b></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi <p> jkl</p></i></b></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi <P> jkl </B>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,38): adoption-agency-1.3",
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi "
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "text": " jkl "
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi </i></b><i><p><b> jkl </b></p></i></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi </i></b><i><p><b> jkl </b></p></i></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi <P> jkl </B> mno",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,38): adoption-agency-1.3",
+        "(1,42): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi "
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "text": " jkl "
+                                  }
+                                ]
+                              },
+                              {
+                                "text": " mno"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi </i></b><i><p><b> jkl </b> mno</p></i></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi </i></b><i><p><b> jkl </b> mno</p></i></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,38): adoption-agency-1.3",
+        "(1,47): adoption-agency-1.3",
+        "(1,47): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi "
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "text": " jkl "
+                                  }
+                                ]
+                              },
+                              {
+                                "text": " mno "
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi </i></b><i></i><p><i><b> jkl </b> mno </i></p></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi </i></b><i></i><p><i><b> jkl </b> mno </i></p></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,38): adoption-agency-1.3",
+        "(1,47): adoption-agency-1.3",
+        "(1,51): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi "
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "text": " jkl "
+                                  }
+                                ]
+                              },
+                              {
+                                "text": " mno "
+                              }
+                            ]
+                          },
+                          {
+                            "text": " pqr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi </i></b><i></i><p><i><b> jkl </b> mno </i> pqr</p></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi </i></b><i></i><p><i><b> jkl </b> mno </i> pqr</p></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr </P>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,38): adoption-agency-1.3",
+        "(1,47): adoption-agency-1.3",
+        "(1,56): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi "
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "text": " jkl "
+                                  }
+                                ]
+                              },
+                              {
+                                "text": " mno "
+                              }
+                            ]
+                          },
+                          {
+                            "text": " pqr "
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi </i></b><i></i><p><i><b> jkl </b> mno </i> pqr </p></div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi </i></b><i></i><p><i><b> jkl </b> mno </i> pqr </p></div>"
+      }
+    },
+    {
+      "data": "<DIV> abc <B> def <I> ghi <P> jkl </B> mno </I> pqr </P> stu",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,38): adoption-agency-1.3",
+        "(1,47): adoption-agency-1.3",
+        "(1,60): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "i": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": " abc "
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": " def "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": " ghi "
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "b",
+                                "children": [
+                                  {
+                                    "text": " jkl "
+                                  }
+                                ]
+                              },
+                              {
+                                "text": " mno "
+                              }
+                            ]
+                          },
+                          {
+                            "text": " pqr "
+                          }
+                        ]
+                      },
+                      {
+                        "text": " stu"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div> abc <b> def <i> ghi </i></b><i></i><p><i><b> jkl </b> mno </i> pqr </p> stu</div></body></html>",
+        "noQuirksBodyHtml": "<div> abc <b> def <i> ghi </i></b><i></i><p><i><b> jkl </b> mno </i> pqr </p> stu</div>"
+      }
+    },
+    {
+      "data": "<test attribute---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->",
+      "errors": [
+        "(1,1040): expected-doctype-but-got-start-tag",
+        "(1,1040): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "test": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "test",
+                    "attrs": [
+                      {
+                        "name": "attribute----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><test attribute----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------=\"\"></test></body></html>",
+        "noQuirksBodyHtml": "<test attribute----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------=\"\"></test>"
+      }
+    },
+    {
+      "data": "<a href=\"blah\">aba<table><a href=\"foo\">br<tr><td></td></tr>x</table>aoe",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag",
+        "(1,39): unexpected-start-tag-implies-table-voodoo",
+        "(1,39): unexpected-start-tag-implies-end-tag",
+        "(1,39): unexpected-end-tag",
+        "(1,45): foster-parenting-character-in-table",
+        "(1,45): foster-parenting-character-in-table",
+        "(1,68): foster-parenting-character-in-table",
+        "(1,71): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "blah"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "aba"
+                      },
+                      {
+                        "tag": "a",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "value": "foo"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "text": "br"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "a",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "value": "foo"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "text": "x"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "foo"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "aoe"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a href=\"blah\">aba<a href=\"foo\">br</a><a href=\"foo\">x</a><table><tbody><tr><td></td></tr></tbody></table></a><a href=\"foo\">aoe</a></body></html>",
+        "noQuirksBodyHtml": "<a href=\"blah\">aba<a href=\"foo\">br</a><a href=\"foo\">x</a><table><tbody><tr><td></td></tr></tbody></table></a><a href=\"foo\">aoe</a>"
+      }
+    },
+    {
+      "data": "<a href=\"blah\">aba<table><tr><td><a href=\"foo\">br</td></tr>x</table>aoe",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag",
+        "(1,54): unexpected-cell-end-tag",
+        "(1,68): unexpected text in table",
+        "(1,71): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "blah"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "abax"
+                      },
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "tag": "a",
+                                        "attrs": [
+                                          {
+                                            "name": "href",
+                                            "value": "foo"
+                                          }
+                                        ],
+                                        "children": [
+                                          {
+                                            "text": "br"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "text": "aoe"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a href=\"blah\">abax<table><tbody><tr><td><a href=\"foo\">br</a></td></tr></tbody></table>aoe</a></body></html>",
+        "noQuirksBodyHtml": "<a href=\"blah\">abax<table><tbody><tr><td><a href=\"foo\">br</a></td></tr></tbody></table>aoe</a>"
+      }
+    },
+    {
+      "data": "<table><a href=\"blah\">aba<tr><td><a href=\"foo\">br</td></tr>x</table>aoe",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,22): unexpected-start-tag-implies-table-voodoo",
+        "(1,29): foster-parenting-character-in-table",
+        "(1,29): foster-parenting-character-in-table",
+        "(1,29): foster-parenting-character-in-table",
+        "(1,54): unexpected-cell-end-tag",
+        "(1,68): foster-parenting-character-in-table",
+        "(1,71): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "blah"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "aba"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "blah"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "x"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "a",
+                                    "attrs": [
+                                      {
+                                        "name": "href",
+                                        "value": "foo"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "text": "br"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "blah"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "aoe"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a href=\"blah\">aba</a><a href=\"blah\">x</a><table><tbody><tr><td><a href=\"foo\">br</a></td></tr></tbody></table><a href=\"blah\">aoe</a></body></html>",
+        "noQuirksBodyHtml": "<a href=\"blah\">aba</a><a href=\"blah\">x</a><table><tbody><tr><td><a href=\"foo\">br</a></td></tr></tbody></table><a href=\"blah\">aoe</a>"
+      }
+    },
+    {
+      "data": "<a href=a>aa<marquee>aa<a href=b>bb</marquee>aa",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,45): end-tag-too-early",
+        "(1,47): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "marquee": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "a"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "aa"
+                      },
+                      {
+                        "tag": "marquee",
+                        "children": [
+                          {
+                            "text": "aa"
+                          },
+                          {
+                            "tag": "a",
+                            "attrs": [
+                              {
+                                "name": "href",
+                                "value": "b"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "text": "bb"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "text": "aa"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a href=\"a\">aa<marquee>aa<a href=\"b\">bb</a></marquee>aa</a></body></html>",
+        "noQuirksBodyHtml": "<a href=\"a\">aa<marquee>aa<a href=\"b\">bb</a></marquee>aa</a>"
+      }
+    },
+    {
+      "data": "<wbr><strike><code></strike><code><strike></code>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,28): adoption-agency-1.3",
+        "(1,49): adoption-agency-1.3",
+        "(1,49): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "wbr": true,
+            "strike": true,
+            "code": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "wbr"
+                  },
+                  {
+                    "tag": "strike",
+                    "children": [
+                      {
+                        "tag": "code"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "code",
+                    "children": [
+                      {
+                        "tag": "code",
+                        "children": [
+                          {
+                            "tag": "strike"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><wbr><strike><code></code></strike><code><code><strike></strike></code></code></body></html>",
+        "noQuirksBodyHtml": "<wbr><strike><code></code></strike><code><code><strike></strike></code></code>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><spacer>foo",
+      "errors": [
+        "(1,26): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "spacer": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "spacer",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><spacer>foo</spacer></body></html>",
+        "noQuirksBodyHtml": "<spacer>foo</spacer>"
+      }
+    },
+    {
+      "data": "<title><meta></title><link><title><meta></title>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "link": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<meta>",
+                        "escaped": true
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "link"
+                  },
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<meta>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title>&lt;meta&gt;</title><link><title>&lt;meta&gt;</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>&lt;meta&gt;</title><link><title>&lt;meta&gt;</title>"
+      }
+    },
+    {
+      "data": "<style><!--</style><meta><script>--><link></script>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "meta": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "meta"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "--><link>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--</style><meta><script>--><link></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<style><!--</style><meta><script>--><link></script>"
+      }
+    },
+    {
+      "data": "<head><meta></head><link>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,25): unexpected-start-tag-out-of-my-head"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "meta": true,
+            "link": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "meta"
+                  },
+                  {
+                    "tag": "link"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><meta><link></head><body></body></html>",
+        "noQuirksBodyHtml": "<meta><link>"
+      }
+    },
+    {
+      "data": "<table><tr><tr><td><td><span><th><span>X</table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,33): unexpected-cell-end-tag",
+        "(1,48): unexpected-cell-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "span": true,
+            "th": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          },
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              },
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "span"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "th",
+                                "children": [
+                                  {
+                                    "tag": "span",
+                                    "children": [
+                                      {
+                                        "text": "X"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr></tr><tr><td></td><td><span></span></td><th><span>X</span></th></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr></tr><tr><td></td><td><span></span></td><th><span>X</span></th></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<body><body><base><link><meta><title><p></title><body><p></body>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,12): unexpected-start-tag",
+        "(1,54): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "base": true,
+            "link": true,
+            "meta": true,
+            "title": true,
+            "p": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "base"
+                  },
+                  {
+                    "tag": "link"
+                  },
+                  {
+                    "tag": "meta"
+                  },
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<p>",
+                        "escaped": true
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><base><link><meta><title>&lt;p&gt;</title><p></p></body></html>",
+        "noQuirksBodyHtml": "<base><link><meta><title>&lt;p&gt;</title><p></p>"
+      }
+    },
+    {
+      "data": "<textarea><p></textarea>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "<p>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><textarea>&lt;p&gt;</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>&lt;p&gt;</textarea>"
+      }
+    },
+    {
+      "data": "<p><image></p>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,10): unexpected-start-tag-treated-as"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "img": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "img"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><img></p></body></html>",
+        "noQuirksBodyHtml": "<p><img></p>"
+      }
+    },
+    {
+      "data": "<a><table><a></table><p><a><div><a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,13): unexpected-start-tag-implies-table-voodoo",
+        "(1,13): unexpected-start-tag-implies-end-tag",
+        "(1,13): adoption-agency-1.3",
+        "(1,27): unexpected-start-tag-implies-end-tag",
+        "(1,27): adoption-agency-1.2",
+        "(1,32): unexpected-end-tag",
+        "(1,35): unexpected-start-tag-implies-end-tag",
+        "(1,35): adoption-agency-1.2",
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "table": true,
+            "p": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "a"
+                      },
+                      {
+                        "tag": "table"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><a></a><table></table></a><p><a></a></p><div><a></a></div></body></html>",
+        "noQuirksBodyHtml": "<a><a></a><table></table></a><p><a></a></p><div><a></a></div>"
+      }
+    },
+    {
+      "data": "<head></p><meta><p>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,10): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "meta": true,
+            "body": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "meta"
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><meta></head><body><p></p></body></html>",
+        "noQuirksBodyHtml": "<p></p><meta><p></p>"
+      }
+    },
+    {
+      "data": "<head></html><meta><p>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,19): expected-eof-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "meta": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "meta"
+                  },
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><meta><p></p></body></html>",
+        "noQuirksBodyHtml": "<meta><p></p>"
+      }
+    },
+    {
+      "data": "<b><table><td><i></table>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-cell-in-table-body",
+        "(1,25): unexpected-cell-end-tag",
+        "(1,25): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "i": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "tag": "i"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><table><tbody><tr><td><i></i></td></tr></tbody></table></b></body></html>",
+        "noQuirksBodyHtml": "<b><table><tbody><tr><td><i></i></td></tr></tbody></table></b>"
+      }
+    },
+    {
+      "data": "<b><table><td></b><i></table>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-cell-in-table-body",
+        "(1,18): unexpected-end-tag",
+        "(1,29): unexpected-cell-end-tag",
+        "(1,29): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "i": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "tag": "i"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><table><tbody><tr><td><i></i></td></tr></tbody></table></b></body></html>",
+        "noQuirksBodyHtml": "<b><table><tbody><tr><td><i></i></td></tr></tbody></table></b>"
+      }
+    },
+    {
+      "data": "<h1><h2>",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag",
+        "(1,8): unexpected-start-tag",
+        "(1,8): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "h1": true,
+            "h2": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "h1"
+                  },
+                  {
+                    "tag": "h2"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><h1></h1><h2></h2></body></html>",
+        "noQuirksBodyHtml": "<h1></h1><h2></h2>"
+      }
+    },
+    {
+      "data": "<a><p><a></a></p></a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,9): unexpected-start-tag-implies-end-tag",
+        "(1,9): adoption-agency-1.3",
+        "(1,21): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a"
+                      },
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a></a><p><a></a><a></a></p></body></html>",
+        "noQuirksBodyHtml": "<a></a><p><a></a><a></a></p>"
+      }
+    },
+    {
+      "data": "<b><button></b></button></b>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,15): adoption-agency-1.3",
+        "(1,28): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "button": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "button",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b></b><button><b></b></button></body></html>",
+        "noQuirksBodyHtml": "<b></b><button><b></b></button>"
+      }
+    },
+    {
+      "data": "<p><b><div><marquee></p></b></div>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-end-tag",
+        "(1,24): unexpected-end-tag",
+        "(1,28): unexpected-end-tag",
+        "(1,34): end-tag-too-early",
+        "(1,34): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "b": true,
+            "div": true,
+            "marquee": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "marquee",
+                            "children": [
+                              {
+                                "tag": "p"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><b></b></p><div><b><marquee><p></p></marquee></b></div></body></html>",
+        "noQuirksBodyHtml": "<p><b></b></p><div><b><marquee><p></p></marquee></b></div>"
+      }
+    },
+    {
+      "data": "<script></script></div><title></title><p><p>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,23): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "title": true,
+            "body": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script"
+                  },
+                  {
+                    "tag": "title"
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></script><title></title></head><body><p></p><p></p></body></html>",
+        "noQuirksBodyHtml": "<script></script><title></title><p></p><p></p>"
+      }
+    },
+    {
+      "data": "<p><hr></p>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "hr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "hr"
+                  },
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p></p><hr><p></p></body></html>",
+        "noQuirksBodyHtml": "<p></p><hr><p></p>"
+      }
+    },
+    {
+      "data": "<select><b><option><select><option></b></select>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-start-tag-in-select",
+        "(1,27): unexpected-select-in-select",
+        "(1,39): unexpected-end-tag",
+        "(1,48): unexpected-end-tag",
+        "(1,48): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "option"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><option></option></select><option></option></body></html>",
+        "noQuirksBodyHtml": "<select><option></option></select><option></option>"
+      }
+    },
+    {
+      "data": "<html><head><title></title><body></body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title></title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title></title>"
+      }
+    },
+    {
+      "data": "<a><table><td><a><table></table><a></tr><a></table><a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-cell-in-table-body",
+        "(1,35): unexpected-start-tag-implies-end-tag",
+        "(1,40): unexpected-cell-end-tag",
+        "(1,43): unexpected-start-tag-implies-table-voodoo",
+        "(1,43): unexpected-start-tag-implies-end-tag",
+        "(1,43): unexpected-end-tag",
+        "(1,54): unexpected-start-tag-implies-end-tag",
+        "(1,54): adoption-agency-1.2",
+        "(1,54): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "a"
+                      },
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "tag": "a",
+                                        "children": [
+                                          {
+                                            "tag": "table"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "a"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><a></a><table><tbody><tr><td><a><table></table></a><a></a></td></tr></tbody></table></a><a></a></body></html>",
+        "noQuirksBodyHtml": "<a><a></a><table><tbody><tr><td><a><table></table></a><a></a></td></tr></tbody></table></a><a></a>"
+      }
+    },
+    {
+      "data": "<ul><li></li><div><li></div><li><li><div><li><address><li><b><em></b><li></ul>",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag",
+        "(1,45): end-tag-too-early",
+        "(1,58): end-tag-too-early",
+        "(1,69): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ul": true,
+            "li": true,
+            "div": true,
+            "address": true,
+            "b": true,
+            "em": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ul",
+                    "children": [
+                      {
+                        "tag": "li"
+                      },
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "li"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "li"
+                      },
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "tag": "address"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "tag": "em"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "li"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ul><li></li><div><li></li></div><li></li><li><div></div></li><li><address></address></li><li><b><em></em></b></li><li></li></ul></body></html>",
+        "noQuirksBodyHtml": "<ul><li></li><div><li></li></div><li></li><li><div></div></li><li><address></address></li><li><b><em></em></b></li><li></li></ul>"
+      }
+    },
+    {
+      "data": "<ul><li><ul></li><li>a</li></ul></li></ul>",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag",
+        "(1,17): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ul": true,
+            "li": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ul",
+                    "children": [
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "tag": "ul",
+                            "children": [
+                              {
+                                "tag": "li",
+                                "children": [
+                                  {
+                                    "text": "a"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ul><li><ul><li>a</li></ul></li></ul></body></html>",
+        "noQuirksBodyHtml": "<ul><li><ul><li>a</li></ul></li></ul>"
+      }
+    },
+    {
+      "data": "<frameset><frame><frameset><frame></frameset><noframes></noframes></frameset>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true,
+            "noframes": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  },
+                  {
+                    "tag": "frameset",
+                    "children": [
+                      {
+                        "tag": "frame"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "noframes"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset><frame><frameset><frame></frameset><noframes></noframes></frameset></html>",
+        "noQuirksBodyHtml": "<noframes></noframes>"
+      }
+    },
+    {
+      "data": "<h1><table><td><h3></table><h3></h1>",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag",
+        "(1,15): unexpected-cell-in-table-body",
+        "(1,27): unexpected-cell-end-tag",
+        "(1,31): unexpected-start-tag",
+        "(1,36): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "h1": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "h3": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "h1",
+                    "children": [
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "tag": "h3"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "h3"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><h1><table><tbody><tr><td><h3></h3></td></tr></tbody></table></h1><h3></h3></body></html>",
+        "noQuirksBodyHtml": "<h1><table><tbody><tr><td><h3></h3></td></tr></tbody></table></h1><h3></h3>"
+      }
+    },
+    {
+      "data": "<table><colgroup><col><colgroup><col><col><col><colgroup><col><col><thead><tr><td></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true,
+            "col": true,
+            "thead": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "col"
+                          },
+                          {
+                            "tag": "col"
+                          },
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "col"
+                          },
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "thead",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup><col></colgroup><colgroup><col><col><col></colgroup><colgroup><col><col></colgroup><thead><tr><td></td></tr></thead></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup><col></colgroup><colgroup><col><col><col></colgroup><colgroup><col><col></colgroup><thead><tr><td></td></tr></thead></table>"
+      }
+    },
+    {
+      "data": "<table><col><tbody><col><tr><col><td><col></table><col>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,37): unexpected-cell-in-table-body",
+        "(1,55): unexpected-start-tag-ignored"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true,
+            "col": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "tbody"
+                      },
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "colgroup",
+                        "children": [
+                          {
+                            "tag": "col"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup><col></colgroup><tbody></tbody><colgroup><col></colgroup><tbody><tr></tr></tbody><colgroup><col></colgroup><tbody><tr><td></td></tr></tbody><colgroup><col></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup><col></colgroup><tbody></tbody><colgroup><col></colgroup><tbody><tr></tr></tbody><colgroup><col></colgroup><tbody><tr><td></td></tr></tbody><colgroup><col></colgroup></table>"
+      }
+    },
+    {
+      "data": "<table><colgroup><tbody><colgroup><tr><colgroup><td><colgroup></table><colgroup>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,52): unexpected-cell-in-table-body",
+        "(1,80): unexpected-start-tag-ignored"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup"
+                      },
+                      {
+                        "tag": "tbody"
+                      },
+                      {
+                        "tag": "colgroup"
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "colgroup"
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "colgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup></colgroup><tbody></tbody><colgroup></colgroup><tbody><tr></tr></tbody><colgroup></colgroup><tbody><tr><td></td></tr></tbody><colgroup></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup></colgroup><tbody></tbody><colgroup></colgroup><tbody><tr></tr></tbody><colgroup></colgroup><tbody><tr><td></td></tr></tbody><colgroup></colgroup></table>"
+      }
+    },
+    {
+      "data": "</strong></b></em></i></u></strike></s></blink></tt></pre></big></small></font></select></h1></h2></h3></h4></h5></h6></body></br></a></img></title></span></style></script></table></th></td></tr></frame></area></link></param></hr></input></col></base></meta></basefont></bgsound></embed></spacer></p></dd></dt></caption></colgroup></tbody></tfoot></thead></address></blockquote></center></dir></div></dl></fieldset></listing></menu></ol></ul></li></nobr></wbr></form></button></marquee></object></html></frameset></head></iframe></image></isindex></noembed></noframes></noscript></optgroup></option></plaintext></textarea>",
+      "errors": [
+        "(1,9): expected-doctype-but-got-end-tag",
+        "(1,9): unexpected-end-tag-before-html",
+        "(1,13): unexpected-end-tag-before-html",
+        "(1,18): unexpected-end-tag-before-html",
+        "(1,22): unexpected-end-tag-before-html",
+        "(1,26): unexpected-end-tag-before-html",
+        "(1,35): unexpected-end-tag-before-html",
+        "(1,39): unexpected-end-tag-before-html",
+        "(1,47): unexpected-end-tag-before-html",
+        "(1,52): unexpected-end-tag-before-html",
+        "(1,58): unexpected-end-tag-before-html",
+        "(1,64): unexpected-end-tag-before-html",
+        "(1,72): unexpected-end-tag-before-html",
+        "(1,79): unexpected-end-tag-before-html",
+        "(1,88): unexpected-end-tag-before-html",
+        "(1,93): unexpected-end-tag-before-html",
+        "(1,98): unexpected-end-tag-before-html",
+        "(1,103): unexpected-end-tag-before-html",
+        "(1,108): unexpected-end-tag-before-html",
+        "(1,113): unexpected-end-tag-before-html",
+        "(1,118): unexpected-end-tag-before-html",
+        "(1,130): unexpected-end-tag-after-body",
+        "(1,130): unexpected-end-tag-treated-as",
+        "(1,134): unexpected-end-tag",
+        "(1,140): unexpected-end-tag",
+        "(1,148): unexpected-end-tag",
+        "(1,155): unexpected-end-tag",
+        "(1,163): unexpected-end-tag",
+        "(1,172): unexpected-end-tag",
+        "(1,180): unexpected-end-tag",
+        "(1,185): unexpected-end-tag",
+        "(1,190): unexpected-end-tag",
+        "(1,195): unexpected-end-tag",
+        "(1,203): unexpected-end-tag",
+        "(1,210): unexpected-end-tag",
+        "(1,217): unexpected-end-tag",
+        "(1,225): unexpected-end-tag",
+        "(1,230): unexpected-end-tag",
+        "(1,238): unexpected-end-tag",
+        "(1,244): unexpected-end-tag",
+        "(1,251): unexpected-end-tag",
+        "(1,258): unexpected-end-tag",
+        "(1,269): unexpected-end-tag",
+        "(1,279): unexpected-end-tag",
+        "(1,287): unexpected-end-tag",
+        "(1,296): unexpected-end-tag",
+        "(1,300): unexpected-end-tag",
+        "(1,305): unexpected-end-tag",
+        "(1,310): unexpected-end-tag",
+        "(1,320): unexpected-end-tag",
+        "(1,331): unexpected-end-tag",
+        "(1,339): unexpected-end-tag",
+        "(1,347): unexpected-end-tag",
+        "(1,355): unexpected-end-tag",
+        "(1,365): end-tag-too-early",
+        "(1,378): end-tag-too-early",
+        "(1,387): end-tag-too-early",
+        "(1,393): end-tag-too-early",
+        "(1,399): end-tag-too-early",
+        "(1,404): end-tag-too-early",
+        "(1,415): end-tag-too-early",
+        "(1,425): end-tag-too-early",
+        "(1,432): end-tag-too-early",
+        "(1,437): end-tag-too-early",
+        "(1,442): end-tag-too-early",
+        "(1,447): unexpected-end-tag",
+        "(1,454): unexpected-end-tag",
+        "(1,460): unexpected-end-tag",
+        "(1,467): unexpected-end-tag",
+        "(1,476): end-tag-too-early",
+        "(1,486): end-tag-too-early",
+        "(1,495): end-tag-too-early",
+        "(1,513): expected-eof-but-got-end-tag",
+        "(1,513): unexpected-end-tag",
+        "(1,520): unexpected-end-tag",
+        "(1,529): unexpected-end-tag",
+        "(1,537): unexpected-end-tag",
+        "(1,547): unexpected-end-tag",
+        "(1,557): unexpected-end-tag",
+        "(1,568): unexpected-end-tag",
+        "(1,579): unexpected-end-tag",
+        "(1,590): unexpected-end-tag",
+        "(1,599): unexpected-end-tag",
+        "(1,611): unexpected-end-tag",
+        "(1,622): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "br": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "br"
+                  },
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><br><p></p></body></html>",
+        "noQuirksBodyHtml": "<br><p></p>"
+      }
+    },
+    {
+      "data": "<table><tr></strong></b></em></i></u></strike></s></blink></tt></pre></big></small></font></select></h1></h2></h3></h4></h5></h6></body></br></a></img></title></span></style></script></table></th></td></tr></frame></area></link></param></hr></input></col></base></meta></basefont></bgsound></embed></spacer></p></dd></dt></caption></colgroup></tbody></tfoot></thead></address></blockquote></center></dir></div></dl></fieldset></listing></menu></ol></ul></li></nobr></wbr></form></button></marquee></object></html></frameset></head></iframe></image></isindex></noembed></noframes></noscript></optgroup></option></plaintext></textarea>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,20): unexpected-end-tag-implies-table-voodoo",
+        "(1,20): unexpected-end-tag",
+        "(1,24): unexpected-end-tag-implies-table-voodoo",
+        "(1,24): unexpected-end-tag",
+        "(1,29): unexpected-end-tag-implies-table-voodoo",
+        "(1,29): unexpected-end-tag",
+        "(1,33): unexpected-end-tag-implies-table-voodoo",
+        "(1,33): unexpected-end-tag",
+        "(1,37): unexpected-end-tag-implies-table-voodoo",
+        "(1,37): unexpected-end-tag",
+        "(1,46): unexpected-end-tag-implies-table-voodoo",
+        "(1,46): unexpected-end-tag",
+        "(1,50): unexpected-end-tag-implies-table-voodoo",
+        "(1,50): unexpected-end-tag",
+        "(1,58): unexpected-end-tag-implies-table-voodoo",
+        "(1,58): unexpected-end-tag",
+        "(1,63): unexpected-end-tag-implies-table-voodoo",
+        "(1,63): unexpected-end-tag",
+        "(1,69): unexpected-end-tag-implies-table-voodoo",
+        "(1,69): end-tag-too-early",
+        "(1,75): unexpected-end-tag-implies-table-voodoo",
+        "(1,75): unexpected-end-tag",
+        "(1,83): unexpected-end-tag-implies-table-voodoo",
+        "(1,83): unexpected-end-tag",
+        "(1,90): unexpected-end-tag-implies-table-voodoo",
+        "(1,90): unexpected-end-tag",
+        "(1,99): unexpected-end-tag-implies-table-voodoo",
+        "(1,99): unexpected-end-tag",
+        "(1,104): unexpected-end-tag-implies-table-voodoo",
+        "(1,104): end-tag-too-early",
+        "(1,109): unexpected-end-tag-implies-table-voodoo",
+        "(1,109): end-tag-too-early",
+        "(1,114): unexpected-end-tag-implies-table-voodoo",
+        "(1,114): end-tag-too-early",
+        "(1,119): unexpected-end-tag-implies-table-voodoo",
+        "(1,119): end-tag-too-early",
+        "(1,124): unexpected-end-tag-implies-table-voodoo",
+        "(1,124): end-tag-too-early",
+        "(1,129): unexpected-end-tag-implies-table-voodoo",
+        "(1,129): end-tag-too-early",
+        "(1,136): unexpected-end-tag-in-table-row",
+        "(1,141): unexpected-end-tag-implies-table-voodoo",
+        "(1,141): unexpected-end-tag-treated-as",
+        "(1,145): unexpected-end-tag-implies-table-voodoo",
+        "(1,145): unexpected-end-tag",
+        "(1,151): unexpected-end-tag-implies-table-voodoo",
+        "(1,151): unexpected-end-tag",
+        "(1,159): unexpected-end-tag-implies-table-voodoo",
+        "(1,159): unexpected-end-tag",
+        "(1,166): unexpected-end-tag-implies-table-voodoo",
+        "(1,166): unexpected-end-tag",
+        "(1,174): unexpected-end-tag-implies-table-voodoo",
+        "(1,174): unexpected-end-tag",
+        "(1,183): unexpected-end-tag-implies-table-voodoo",
+        "(1,183): unexpected-end-tag",
+        "(1,196): unexpected-end-tag",
+        "(1,201): unexpected-end-tag",
+        "(1,206): unexpected-end-tag",
+        "(1,214): unexpected-end-tag",
+        "(1,221): unexpected-end-tag",
+        "(1,228): unexpected-end-tag",
+        "(1,236): unexpected-end-tag",
+        "(1,241): unexpected-end-tag",
+        "(1,249): unexpected-end-tag",
+        "(1,255): unexpected-end-tag",
+        "(1,262): unexpected-end-tag",
+        "(1,269): unexpected-end-tag",
+        "(1,280): unexpected-end-tag",
+        "(1,290): unexpected-end-tag",
+        "(1,298): unexpected-end-tag",
+        "(1,307): unexpected-end-tag",
+        "(1,311): unexpected-end-tag",
+        "(1,316): unexpected-end-tag",
+        "(1,321): unexpected-end-tag",
+        "(1,331): unexpected-end-tag",
+        "(1,342): unexpected-end-tag",
+        "(1,350): unexpected-end-tag",
+        "(1,358): unexpected-end-tag",
+        "(1,366): unexpected-end-tag",
+        "(1,376): end-tag-too-early",
+        "(1,389): end-tag-too-early",
+        "(1,398): end-tag-too-early",
+        "(1,404): end-tag-too-early",
+        "(1,410): end-tag-too-early",
+        "(1,415): end-tag-too-early",
+        "(1,426): end-tag-too-early",
+        "(1,436): end-tag-too-early",
+        "(1,443): end-tag-too-early",
+        "(1,448): end-tag-too-early",
+        "(1,453): end-tag-too-early",
+        "(1,458): unexpected-end-tag",
+        "(1,465): unexpected-end-tag",
+        "(1,471): unexpected-end-tag",
+        "(1,478): unexpected-end-tag",
+        "(1,487): end-tag-too-early",
+        "(1,497): end-tag-too-early",
+        "(1,506): end-tag-too-early",
+        "(1,524): expected-eof-but-got-end-tag",
+        "(1,524): unexpected-end-tag",
+        "(1,531): unexpected-end-tag",
+        "(1,540): unexpected-end-tag",
+        "(1,548): unexpected-end-tag",
+        "(1,558): unexpected-end-tag",
+        "(1,568): unexpected-end-tag",
+        "(1,579): unexpected-end-tag",
+        "(1,590): unexpected-end-tag",
+        "(1,601): unexpected-end-tag",
+        "(1,610): unexpected-end-tag",
+        "(1,622): unexpected-end-tag",
+        "(1,633): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "br": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "br"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><br><table><tbody><tr></tr></tbody></table><p></p></body></html>",
+        "noQuirksBodyHtml": "<br><table><tbody><tr></tr></tbody></table><p></p>"
+      }
+    },
+    {
+      "data": "<frameset>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,10): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    }
+  ],
+  "tests10.dat": [
+    {
+      "data": "<!DOCTYPE html><svg></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg></svg></body></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><svg></svg><![CDATA[a]]>",
+      "errors": [
+        "(1,28) expected-dashes-or-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  },
+                  {
+                    "comment": "[CDATA[a]]"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg></svg><!--[CDATA[a]]--></body></html>",
+        "noQuirksBodyHtml": "<svg></svg><!--[CDATA[a]]-->"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><svg></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg></svg></body></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><select><svg></svg></select>",
+      "errors": [
+        "(1,34) unexpected-start-tag-in-select",
+        "(1,40) unexpected-end-tag-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><select><option><svg></svg></option></select>",
+      "errors": [
+        "(1,42) unexpected-start-tag-in-select",
+        "(1,48) unexpected-end-tag-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><option></option></select></body></html>",
+        "noQuirksBodyHtml": "<select><option></option></select>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><svg></svg></table>",
+      "errors": [
+        "(1,33) foster-parenting-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg></svg><table></table></body></html>",
+        "noQuirksBodyHtml": "<svg></svg><table></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><svg><g>foo</g></svg></table>",
+      "errors": [
+        "(1,33) foster-parenting-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><g>foo</g></svg><table></table></body></html>",
+        "noQuirksBodyHtml": "<svg><g>foo</g></svg><table></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><svg><g>foo</g><g>bar</g></svg></table>",
+      "errors": [
+        "(1,33) foster-parenting-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><g>foo</g><g>bar</g></svg><table></table></body></html>",
+        "noQuirksBodyHtml": "<svg><g>foo</g><g>bar</g></svg><table></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tbody><svg><g>foo</g><g>bar</g></svg></tbody></table>",
+      "errors": [
+        "(1,40) foster-parenting-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true,
+            "table": true,
+            "tbody": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><g>foo</g><g>bar</g></svg><table><tbody></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<svg><g>foo</g><g>bar</g></svg><table><tbody></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tbody><tr><svg><g>foo</g><g>bar</g></svg></tr></tbody></table>",
+      "errors": [
+        "(1,44) foster-parenting-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><g>foo</g><g>bar</g></svg><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<svg><g>foo</g><g>bar</g></svg><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg></td></tr></tbody></table>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg g": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "g",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "text": "foo"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "g",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "text": "bar"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg><p>baz</td></tr></tbody></table>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg g": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "g",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "text": "foo"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "g",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "text": "bar"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "tag": "p",
+                                    "children": [
+                                      {
+                                        "text": "baz"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg><p>baz</p></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg><p>baz</p></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g></svg><p>baz</caption></table>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "svg svg": true,
+            "svg g": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "g",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "text": "foo"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "g",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "text": "bar"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "text": "baz"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><svg><g>foo</g><g>bar</g></svg><p>baz</p></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption><svg><g>foo</g><g>bar</g></svg><p>baz</p></caption></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g><p>baz</table><p>quux",
+      "errors": [
+        "(1,65) unexpected-html-element-in-foreign-content"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "svg svg": true,
+            "svg g": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "g",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "text": "foo"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "g",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "text": "bar"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "text": "baz"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><svg><g>foo</g><g>bar</g></svg><p>baz</p></caption></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<table><caption><svg><g>foo</g><g>bar</g><p>baz</p></svg></caption></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g>baz</table><p>quux",
+      "errors": [
+        "(1,73) unexpected-end-tag",
+        "(1,73) expected-one-end-tag-but-got-another"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "svg svg": true,
+            "svg g": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "g",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "text": "foo"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "g",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "text": "bar"
+                                  }
+                                ]
+                              },
+                              {
+                                "text": "baz"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><svg><g>foo</g><g>bar</g>baz</svg></caption></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<table><caption><svg><g>foo</g><g>bar</g>baz</svg></caption></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><colgroup><svg><g>foo</g><g>bar</g><p>baz</table><p>quux",
+      "errors": [
+        "(1,43) foster-parenting-start-tag svg",
+        "(1,66) unexpected HTML-like start tag token in foreign content",
+        "(1,66) foster-parenting-start-tag",
+        "(1,67) foster-parenting-character",
+        "(1,68) foster-parenting-character",
+        "(1,69) foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true,
+            "p": true,
+            "table": true,
+            "colgroup": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "baz"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><g>foo</g><g>bar</g></svg><p>baz</p><table><colgroup></colgroup></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<svg><g>foo</g><g>bar</g><p>baz</p></svg><table><colgroup></colgroup></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tr><td><select><svg><g>foo</g><g>bar</g><p>baz</table><p>quux",
+      "errors": [
+        "(1,49) unexpected-start-tag-in-select",
+        "(1,52) unexpected-start-tag-in-select",
+        "(1,59) unexpected-end-tag-in-select",
+        "(1,62) unexpected-start-tag-in-select",
+        "(1,69) unexpected-end-tag-in-select",
+        "(1,72) unexpected-start-tag-in-select",
+        "(1,83) unexpected-table-element-end-tag-in-select-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "select": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "select",
+                                    "children": [
+                                      {
+                                        "text": "foobarbaz"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><select>foobarbaz</select></td></tr></tbody></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><select>foobarbaz</select></td></tr></tbody></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><select><svg><g>foo</g><g>bar</g><p>baz</table><p>quux",
+      "errors": [
+        "(1,36) unexpected-start-tag-implies-table-voodoo",
+        "(1,41) unexpected-start-tag-in-select",
+        "(1,44) unexpected-start-tag-in-select",
+        "(1,51) unexpected-end-tag-in-select",
+        "(1,54) unexpected-start-tag-in-select",
+        "(1,61) unexpected-end-tag-in-select",
+        "(1,64) unexpected-start-tag-in-select",
+        "(1,75) unexpected-table-element-end-tag-in-select-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "table": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "text": "foobarbaz"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select>foobarbaz</select><table></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<select>foobarbaz</select><table></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body></body></html><svg><g>foo</g><g>bar</g><p>baz",
+      "errors": [
+        "(1,40) expected-eof-but-got-start-tag",
+        "(1,63) unexpected-html-element-in-foreign-content"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "baz"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><g>foo</g><g>bar</g></svg><p>baz</p></body></html>",
+        "noQuirksBodyHtml": "<svg><g>foo</g><g>bar</g><p>baz</p></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body></body><svg><g>foo</g><g>bar</g><p>baz",
+      "errors": [
+        "(1,33) unexpected-start-tag-after-body",
+        "(1,56) unexpected-html-element-in-foreign-content"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "baz"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><g>foo</g><g>bar</g></svg><p>baz</p></body></html>",
+        "noQuirksBodyHtml": "<svg><g>foo</g><g>bar</g><p>baz</p></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><frameset><svg><g></g><g></g><p><span>",
+      "errors": [
+        "(1,30) unexpected-start-tag-in-frameset",
+        "(1,33) unexpected-start-tag-in-frameset",
+        "(1,37) unexpected-end-tag-in-frameset",
+        "(1,40) unexpected-start-tag-in-frameset",
+        "(1,44) unexpected-end-tag-in-frameset",
+        "(1,47) unexpected-start-tag-in-frameset",
+        "(1,53) unexpected-start-tag-in-frameset",
+        "(1,53) eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<svg><g></g><g></g><p><span></span></p></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><frameset></frameset><svg><g></g><g></g><p><span>",
+      "errors": [
+        "(1,41) unexpected-start-tag-after-frameset",
+        "(1,44) unexpected-start-tag-after-frameset",
+        "(1,48) unexpected-end-tag-after-frameset",
+        "(1,51) unexpected-start-tag-after-frameset",
+        "(1,55) unexpected-end-tag-after-frameset",
+        "(1,58) unexpected-start-tag-after-frameset",
+        "(1,64) unexpected-start-tag-after-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<svg><g></g><g></g><p><span></span></p></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body xlink:href=foo><svg xlink:href=foo></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "xlink:href",
+                    "value": "foo"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "ns": "http://www.w3.org/1999/xlink",
+                        "value": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body xlink:href=\"foo\"><svg xlink:href=\"foo\"></svg></body></html>",
+        "noQuirksBodyHtml": "<svg xlink:href=\"foo\"></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo></g></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "xlink:href",
+                    "value": "foo"
+                  },
+                  {
+                    "name": "xml:lang",
+                    "value": "en"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "ns": "http://www.w3.org/1999/xlink",
+                            "value": "foo"
+                          },
+                          {
+                            "name": "lang",
+                            "ns": "http://www.w3.org/XML/1998/namespace",
+                            "value": "en"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body xlink:href=\"foo\" xml:lang=\"en\"><svg><g xml:lang=\"en\" xlink:href=\"foo\"></g></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><g xml:lang=\"en\" xlink:href=\"foo\"></g></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo /></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "xlink:href",
+                    "value": "foo"
+                  },
+                  {
+                    "name": "xml:lang",
+                    "value": "en"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "ns": "http://www.w3.org/1999/xlink",
+                            "value": "foo"
+                          },
+                          {
+                            "name": "lang",
+                            "ns": "http://www.w3.org/XML/1998/namespace",
+                            "value": "en"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body xlink:href=\"foo\" xml:lang=\"en\"><svg><g xml:lang=\"en\" xlink:href=\"foo\"></g></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><g xml:lang=\"en\" xlink:href=\"foo\"></g></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo />bar</svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg g": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "xlink:href",
+                    "value": "foo"
+                  },
+                  {
+                    "name": "xml:lang",
+                    "value": "en"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "g",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "ns": "http://www.w3.org/1999/xlink",
+                            "value": "foo"
+                          },
+                          {
+                            "name": "lang",
+                            "ns": "http://www.w3.org/XML/1998/namespace",
+                            "value": "en"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "bar"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body xlink:href=\"foo\" xml:lang=\"en\"><svg><g xml:lang=\"en\" xlink:href=\"foo\"></g>bar</svg></body></html>",
+        "noQuirksBodyHtml": "<svg><g xml:lang=\"en\" xlink:href=\"foo\"></g>bar</svg>"
+      }
+    },
+    {
+      "data": "<svg></path>",
+      "errors": [
+        "(1,5) expected-doctype-but-got-start-tag",
+        "(1,12) unexpected-end-tag",
+        "(1,12) unexpected-end-tag",
+        "(1,12) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg></body></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<div><svg></div>a",
+      "errors": [
+        "(1,5) expected-doctype-but-got-start-tag",
+        "(1,16) unexpected-end-tag",
+        "(1,16) end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><svg></svg></div>a</body></html>",
+        "noQuirksBodyHtml": "<div><svg></svg></div>a"
+      }
+    },
+    {
+      "data": "<div><svg><path></div>a",
+      "errors": [
+        "(1,5) expected-doctype-but-got-start-tag",
+        "(1,22) unexpected-end-tag",
+        "(1,22) end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "svg svg": true,
+            "svg path": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "path",
+                            "ns": "http://www.w3.org/2000/svg"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><svg><path></path></svg></div>a</body></html>",
+        "noQuirksBodyHtml": "<div><svg><path></path></svg></div>a"
+      }
+    },
+    {
+      "data": "<div><svg><path></svg><path>",
+      "errors": [
+        "(1,5) expected-doctype-but-got-start-tag",
+        "(1,22) unexpected-end-tag",
+        "(1,28) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "svg svg": true,
+            "svg path": true,
+            "path": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "path",
+                            "ns": "http://www.w3.org/2000/svg"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "path"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><svg><path></path></svg><path></path></div></body></html>",
+        "noQuirksBodyHtml": "<div><svg><path></path></svg><path></path></div>"
+      }
+    },
+    {
+      "data": "<div><svg><path><foreignObject><math></div>a",
+      "errors": [
+        "(1,5) expected-doctype-but-got-start-tag",
+        "(1,43) unexpected-end-tag",
+        "(1,43) end-tag-too-early",
+        "(1,44) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "svg svg": true,
+            "svg path": true,
+            "svg foreignObject": true,
+            "math math": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "path",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "foreignObject",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "math",
+                                    "ns": "http://www.w3.org/1998/Math/MathML",
+                                    "children": [
+                                      {
+                                        "text": "a"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><svg><path><foreignObject><math>a</math></foreignObject></path></svg></div></body></html>",
+        "noQuirksBodyHtml": "<div><svg><path><foreignObject><math>a</math></foreignObject></path></svg></div>"
+      }
+    },
+    {
+      "data": "<div><svg><path><foreignObject><p></div>a",
+      "errors": [
+        "(1,5) expected-doctype-but-got-start-tag",
+        "(1,40) end-tag-too-early",
+        "(1,41) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "svg svg": true,
+            "svg path": true,
+            "svg foreignObject": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "path",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "foreignObject",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "p",
+                                    "children": [
+                                      {
+                                        "text": "a"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><svg><path><foreignObject><p>a</p></foreignObject></path></svg></div></body></html>",
+        "noQuirksBodyHtml": "<div><svg><path><foreignObject><p>a</p></foreignObject></path></svg></div>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><svg><desc><div><svg><ul>a",
+      "errors": [
+        "(1,40) unexpected-html-element-in-foreign-content",
+        "(1,41) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg desc": true,
+            "div": true,
+            "ul": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "desc",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "tag": "svg",
+                                "ns": "http://www.w3.org/2000/svg"
+                              },
+                              {
+                                "tag": "ul",
+                                "children": [
+                                  {
+                                    "text": "a"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><desc><div><svg></svg><ul>a</ul></div></desc></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><desc><div><svg><ul>a</ul></svg></div></desc></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><svg><desc><svg><ul>a",
+      "errors": [
+        "(1,35) unexpected-html-element-in-foreign-content",
+        "(1,36) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg desc": true,
+            "ul": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "desc",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg"
+                          },
+                          {
+                            "tag": "ul",
+                            "children": [
+                              {
+                                "text": "a"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><desc><svg></svg><ul>a</ul></desc></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><desc><svg><ul>a</ul></svg></desc></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><p><svg><desc><p>",
+      "errors": [
+        "(1,32) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "svg svg": true,
+            "svg desc": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "desc",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "p"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><svg><desc><p></p></desc></svg></p></body></html>",
+        "noQuirksBodyHtml": "<p><svg><desc><p></p></desc></svg></p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><p><svg><title><p>",
+      "errors": [
+        "(1,33) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "svg svg": true,
+            "svg title": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "title",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "p"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><svg><title><p></p></title></svg></p></body></html>",
+        "noQuirksBodyHtml": "<p><svg><title><p></p></title></svg></p>"
+      }
+    },
+    {
+      "data": "<div><svg><path><foreignObject><p></foreignObject><p>",
+      "errors": [
+        "(1,5) expected-doctype-but-got-start-tag",
+        "(1,50) unexpected-end-tag",
+        "(1,53) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "svg svg": true,
+            "svg path": true,
+            "svg foreignObject": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "svg",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "path",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "foreignObject",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "p"
+                                  },
+                                  {
+                                    "tag": "p"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><svg><path><foreignObject><p></p><p></p></foreignObject></path></svg></div></body></html>",
+        "noQuirksBodyHtml": "<div><svg><path><foreignObject><p></p><p></p></foreignObject></path></svg></div>"
+      }
+    },
+    {
+      "data": "<math><mi><div><object><div><span></span></div></object></div></mi><mi>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,71) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "div": true,
+            "object": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "tag": "object",
+                                "children": [
+                                  {
+                                    "tag": "div",
+                                    "children": [
+                                      {
+                                        "tag": "span"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mi><div><object><div><span></span></div></object></div></mi><mi></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><mi><div><object><div><span></span></div></object></div></mi><mi></mi></math>"
+      }
+    },
+    {
+      "data": "<math><mi><svg><foreignObject><div><div></div></div></foreignObject></svg></mi><mi>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,83) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "foreignObject",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "div",
+                                    "children": [
+                                      {
+                                        "tag": "div"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mi><svg><foreignObject><div><div></div></div></foreignObject></svg></mi><mi></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><mi><svg><foreignObject><div><div></div></div></foreignObject></svg></mi><mi></mi></math>"
+      }
+    },
+    {
+      "data": "<svg><script></script><path>",
+      "errors": [
+        "(1,5) expected-doctype-but-got-start-tag",
+        "(1,28) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg script": true,
+            "svg path": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "script",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "path",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><script></script><path></path></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><script></script><path></path></svg>"
+      }
+    },
+    {
+      "data": "<table><svg></svg><tr>",
+      "errors": [
+        "(1,7) expected-doctype-but-got-start-tag",
+        "(1,12) unexpected-start-tag-implies-table-voodoo",
+        "(1,22) eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<svg></svg><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<math><mi><mglyph>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,18) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "math mglyph": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mglyph",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mi><mglyph></mglyph></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><mi><mglyph></mglyph></mi></math>"
+      }
+    },
+    {
+      "data": "<math><mi><malignmark>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,22) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "malignmark",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mi><malignmark></malignmark></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><mi><malignmark></malignmark></mi></math>"
+      }
+    },
+    {
+      "data": "<math><mo><mglyph>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,18) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mo": true,
+            "math mglyph": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mo",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mglyph",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mo><mglyph></mglyph></mo></math></body></html>",
+        "noQuirksBodyHtml": "<math><mo><mglyph></mglyph></mo></math>"
+      }
+    },
+    {
+      "data": "<math><mo><malignmark>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,22) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mo": true,
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mo",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "malignmark",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mo><malignmark></malignmark></mo></math></body></html>",
+        "noQuirksBodyHtml": "<math><mo><malignmark></malignmark></mo></math>"
+      }
+    },
+    {
+      "data": "<math><mn><mglyph>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,18) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mn": true,
+            "math mglyph": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mn",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mglyph",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mn><mglyph></mglyph></mn></math></body></html>",
+        "noQuirksBodyHtml": "<math><mn><mglyph></mglyph></mn></math>"
+      }
+    },
+    {
+      "data": "<math><mn><malignmark>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,22) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mn": true,
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mn",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "malignmark",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mn><malignmark></malignmark></mn></math></body></html>",
+        "noQuirksBodyHtml": "<math><mn><malignmark></malignmark></mn></math>"
+      }
+    },
+    {
+      "data": "<math><ms><mglyph>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,18) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math ms": true,
+            "math mglyph": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "ms",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mglyph",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><ms><mglyph></mglyph></ms></math></body></html>",
+        "noQuirksBodyHtml": "<math><ms><mglyph></mglyph></ms></math>"
+      }
+    },
+    {
+      "data": "<math><ms><malignmark>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,22) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math ms": true,
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "ms",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "malignmark",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><ms><malignmark></malignmark></ms></math></body></html>",
+        "noQuirksBodyHtml": "<math><ms><malignmark></malignmark></ms></math>"
+      }
+    },
+    {
+      "data": "<math><mtext><mglyph>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,21) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mtext": true,
+            "math mglyph": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mtext",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mglyph",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mtext><mglyph></mglyph></mtext></math></body></html>",
+        "noQuirksBodyHtml": "<math><mtext><mglyph></mglyph></mtext></math>"
+      }
+    },
+    {
+      "data": "<math><mtext><malignmark>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,25) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mtext": true,
+            "math malignmark": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mtext",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "malignmark",
+                            "ns": "http://www.w3.org/1998/Math/MathML"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mtext><malignmark></malignmark></mtext></math></body></html>",
+        "noQuirksBodyHtml": "<math><mtext><malignmark></malignmark></mtext></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml><svg></svg></annotation-xml><mi>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,54) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "svg svg": true,
+            "math mi": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml><svg></svg></annotation-xml><mi></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml><svg></svg></annotation-xml><mi></mi></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml><svg><foreignObject><div><math><mi></mi></math><span></span></div></foreignObject><path></path></svg></annotation-xml><mi>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,144) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "div": true,
+            "math mi": true,
+            "span": true,
+            "svg path": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "foreignObject",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "div",
+                                    "children": [
+                                      {
+                                        "tag": "math",
+                                        "ns": "http://www.w3.org/1998/Math/MathML",
+                                        "children": [
+                                          {
+                                            "tag": "mi",
+                                            "ns": "http://www.w3.org/1998/Math/MathML"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "span"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "path",
+                                "ns": "http://www.w3.org/2000/svg"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml><svg><foreignObject><div><math><mi></mi></math><span></span></div></foreignObject><path></path></svg></annotation-xml><mi></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml><svg><foreignObject><div><math><mi></mi></math><span></span></div></foreignObject><path></path></svg></annotation-xml><mi></mi></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml><svg><foreignObject><math><mi><svg></svg></mi><mo></mo></math><span></span></foreignObject><path></path></svg></annotation-xml><mi>",
+      "errors": [
+        "(1,6) expected-doctype-but-got-start-tag",
+        "(1,153) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "math mi": true,
+            "math mo": true,
+            "span": true,
+            "svg path": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "foreignObject",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "math",
+                                    "ns": "http://www.w3.org/1998/Math/MathML",
+                                    "children": [
+                                      {
+                                        "tag": "mi",
+                                        "ns": "http://www.w3.org/1998/Math/MathML",
+                                        "children": [
+                                          {
+                                            "tag": "svg",
+                                            "ns": "http://www.w3.org/2000/svg"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "mo",
+                                        "ns": "http://www.w3.org/1998/Math/MathML"
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "tag": "span"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "path",
+                                "ns": "http://www.w3.org/2000/svg"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml><svg><foreignObject><math><mi><svg></svg></mi><mo></mo></math><span></span></foreignObject><path></path></svg></annotation-xml><mi></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml><svg><foreignObject><math><mi><svg></svg></mi><mo></mo></math><span></span></foreignObject><path></path></svg></annotation-xml><mi></mi></math>"
+      }
+    }
+  ],
+  "tests11.dat": [
+    {
+      "data": "<!DOCTYPE html><body><svg attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' diffuseConstant='' edgeMode='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "attrs": [
+                      {
+                        "name": "attributeName",
+                        "value": ""
+                      },
+                      {
+                        "name": "attributeType",
+                        "value": ""
+                      },
+                      {
+                        "name": "baseFrequency",
+                        "value": ""
+                      },
+                      {
+                        "name": "baseProfile",
+                        "value": ""
+                      },
+                      {
+                        "name": "calcMode",
+                        "value": ""
+                      },
+                      {
+                        "name": "clipPathUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "diffuseConstant",
+                        "value": ""
+                      },
+                      {
+                        "name": "edgeMode",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "glyphRef",
+                        "value": ""
+                      },
+                      {
+                        "name": "gradientTransform",
+                        "value": ""
+                      },
+                      {
+                        "name": "gradientUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "kernelMatrix",
+                        "value": ""
+                      },
+                      {
+                        "name": "kernelUnitLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "keyPoints",
+                        "value": ""
+                      },
+                      {
+                        "name": "keySplines",
+                        "value": ""
+                      },
+                      {
+                        "name": "keyTimes",
+                        "value": ""
+                      },
+                      {
+                        "name": "lengthAdjust",
+                        "value": ""
+                      },
+                      {
+                        "name": "limitingConeAngle",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerHeight",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerWidth",
+                        "value": ""
+                      },
+                      {
+                        "name": "maskContentUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "maskUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "numOctaves",
+                        "value": ""
+                      },
+                      {
+                        "name": "pathLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternContentUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternTransform",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtX",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtY",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtZ",
+                        "value": ""
+                      },
+                      {
+                        "name": "preserveAlpha",
+                        "value": ""
+                      },
+                      {
+                        "name": "preserveAspectRatio",
+                        "value": ""
+                      },
+                      {
+                        "name": "primitiveUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "refX",
+                        "value": ""
+                      },
+                      {
+                        "name": "refY",
+                        "value": ""
+                      },
+                      {
+                        "name": "repeatCount",
+                        "value": ""
+                      },
+                      {
+                        "name": "repeatDur",
+                        "value": ""
+                      },
+                      {
+                        "name": "requiredExtensions",
+                        "value": ""
+                      },
+                      {
+                        "name": "requiredFeatures",
+                        "value": ""
+                      },
+                      {
+                        "name": "specularConstant",
+                        "value": ""
+                      },
+                      {
+                        "name": "specularExponent",
+                        "value": ""
+                      },
+                      {
+                        "name": "spreadMethod",
+                        "value": ""
+                      },
+                      {
+                        "name": "startOffset",
+                        "value": ""
+                      },
+                      {
+                        "name": "stdDeviation",
+                        "value": ""
+                      },
+                      {
+                        "name": "stitchTiles",
+                        "value": ""
+                      },
+                      {
+                        "name": "surfaceScale",
+                        "value": ""
+                      },
+                      {
+                        "name": "systemLanguage",
+                        "value": ""
+                      },
+                      {
+                        "name": "tableValues",
+                        "value": ""
+                      },
+                      {
+                        "name": "targetX",
+                        "value": ""
+                      },
+                      {
+                        "name": "targetY",
+                        "value": ""
+                      },
+                      {
+                        "name": "textLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "viewBox",
+                        "value": ""
+                      },
+                      {
+                        "name": "viewTarget",
+                        "value": ""
+                      },
+                      {
+                        "name": "xChannelSelector",
+                        "value": ""
+                      },
+                      {
+                        "name": "yChannelSelector",
+                        "value": ""
+                      },
+                      {
+                        "name": "zoomAndPan",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg attributeName=\"\" attributeType=\"\" baseFrequency=\"\" baseProfile=\"\" calcMode=\"\" clipPathUnits=\"\" diffuseConstant=\"\" edgeMode=\"\" filterUnits=\"\" glyphRef=\"\" gradientTransform=\"\" gradientUnits=\"\" kernelMatrix=\"\" kernelUnitLength=\"\" keyPoints=\"\" keySplines=\"\" keyTimes=\"\" lengthAdjust=\"\" limitingConeAngle=\"\" markerHeight=\"\" markerUnits=\"\" markerWidth=\"\" maskContentUnits=\"\" maskUnits=\"\" numOctaves=\"\" pathLength=\"\" patternContentUnits=\"\" patternTransform=\"\" patternUnits=\"\" pointsAtX=\"\" pointsAtY=\"\" pointsAtZ=\"\" preserveAlpha=\"\" preserveAspectRatio=\"\" primitiveUnits=\"\" refX=\"\" refY=\"\" repeatCount=\"\" repeatDur=\"\" requiredExtensions=\"\" requiredFeatures=\"\" specularConstant=\"\" specularExponent=\"\" spreadMethod=\"\" startOffset=\"\" stdDeviation=\"\" stitchTiles=\"\" surfaceScale=\"\" systemLanguage=\"\" tableValues=\"\" targetX=\"\" targetY=\"\" textLength=\"\" viewBox=\"\" viewTarget=\"\" xChannelSelector=\"\" yChannelSelector=\"\" zoomAndPan=\"\"></svg></body></html>",
+        "noQuirksBodyHtml": "<svg attributeName=\"\" attributeType=\"\" baseFrequency=\"\" baseProfile=\"\" calcMode=\"\" clipPathUnits=\"\" diffuseConstant=\"\" edgeMode=\"\" filterUnits=\"\" glyphRef=\"\" gradientTransform=\"\" gradientUnits=\"\" kernelMatrix=\"\" kernelUnitLength=\"\" keyPoints=\"\" keySplines=\"\" keyTimes=\"\" lengthAdjust=\"\" limitingConeAngle=\"\" markerHeight=\"\" markerUnits=\"\" markerWidth=\"\" maskContentUnits=\"\" maskUnits=\"\" numOctaves=\"\" pathLength=\"\" patternContentUnits=\"\" patternTransform=\"\" patternUnits=\"\" pointsAtX=\"\" pointsAtY=\"\" pointsAtZ=\"\" preserveAlpha=\"\" preserveAspectRatio=\"\" primitiveUnits=\"\" refX=\"\" refY=\"\" repeatCount=\"\" repeatDur=\"\" requiredExtensions=\"\" requiredFeatures=\"\" specularConstant=\"\" specularExponent=\"\" spreadMethod=\"\" startOffset=\"\" stdDeviation=\"\" stitchTiles=\"\" surfaceScale=\"\" systemLanguage=\"\" tableValues=\"\" targetX=\"\" targetY=\"\" textLength=\"\" viewBox=\"\" viewTarget=\"\" xChannelSelector=\"\" yChannelSelector=\"\" zoomAndPan=\"\"></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><BODY><SVG ATTRIBUTENAME='' ATTRIBUTETYPE='' BASEFREQUENCY='' BASEPROFILE='' CALCMODE='' CLIPPATHUNITS='' DIFFUSECONSTANT='' EDGEMODE='' FILTERUNITS='' GLYPHREF='' GRADIENTTRANSFORM='' GRADIENTUNITS='' KERNELMATRIX='' KERNELUNITLENGTH='' KEYPOINTS='' KEYSPLINES='' KEYTIMES='' LENGTHADJUST='' LIMITINGCONEANGLE='' MARKERHEIGHT='' MARKERUNITS='' MARKERWIDTH='' MASKCONTENTUNITS='' MASKUNITS='' NUMOCTAVES='' PATHLENGTH='' PATTERNCONTENTUNITS='' PATTERNTRANSFORM='' PATTERNUNITS='' POINTSATX='' POINTSATY='' POINTSATZ='' PRESERVEALPHA='' PRESERVEASPECTRATIO='' PRIMITIVEUNITS='' REFX='' REFY='' REPEATCOUNT='' REPEATDUR='' REQUIREDEXTENSIONS='' REQUIREDFEATURES='' SPECULARCONSTANT='' SPECULAREXPONENT='' SPREADMETHOD='' STARTOFFSET='' STDDEVIATION='' STITCHTILES='' SURFACESCALE='' SYSTEMLANGUAGE='' TABLEVALUES='' TARGETX='' TARGETY='' TEXTLENGTH='' VIEWBOX='' VIEWTARGET='' XCHANNELSELECTOR='' YCHANNELSELECTOR='' ZOOMANDPAN=''></SVG>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "attrs": [
+                      {
+                        "name": "attributeName",
+                        "value": ""
+                      },
+                      {
+                        "name": "attributeType",
+                        "value": ""
+                      },
+                      {
+                        "name": "baseFrequency",
+                        "value": ""
+                      },
+                      {
+                        "name": "baseProfile",
+                        "value": ""
+                      },
+                      {
+                        "name": "calcMode",
+                        "value": ""
+                      },
+                      {
+                        "name": "clipPathUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "diffuseConstant",
+                        "value": ""
+                      },
+                      {
+                        "name": "edgeMode",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "glyphRef",
+                        "value": ""
+                      },
+                      {
+                        "name": "gradientTransform",
+                        "value": ""
+                      },
+                      {
+                        "name": "gradientUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "kernelMatrix",
+                        "value": ""
+                      },
+                      {
+                        "name": "kernelUnitLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "keyPoints",
+                        "value": ""
+                      },
+                      {
+                        "name": "keySplines",
+                        "value": ""
+                      },
+                      {
+                        "name": "keyTimes",
+                        "value": ""
+                      },
+                      {
+                        "name": "lengthAdjust",
+                        "value": ""
+                      },
+                      {
+                        "name": "limitingConeAngle",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerHeight",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerWidth",
+                        "value": ""
+                      },
+                      {
+                        "name": "maskContentUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "maskUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "numOctaves",
+                        "value": ""
+                      },
+                      {
+                        "name": "pathLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternContentUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternTransform",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtX",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtY",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtZ",
+                        "value": ""
+                      },
+                      {
+                        "name": "preserveAlpha",
+                        "value": ""
+                      },
+                      {
+                        "name": "preserveAspectRatio",
+                        "value": ""
+                      },
+                      {
+                        "name": "primitiveUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "refX",
+                        "value": ""
+                      },
+                      {
+                        "name": "refY",
+                        "value": ""
+                      },
+                      {
+                        "name": "repeatCount",
+                        "value": ""
+                      },
+                      {
+                        "name": "repeatDur",
+                        "value": ""
+                      },
+                      {
+                        "name": "requiredExtensions",
+                        "value": ""
+                      },
+                      {
+                        "name": "requiredFeatures",
+                        "value": ""
+                      },
+                      {
+                        "name": "specularConstant",
+                        "value": ""
+                      },
+                      {
+                        "name": "specularExponent",
+                        "value": ""
+                      },
+                      {
+                        "name": "spreadMethod",
+                        "value": ""
+                      },
+                      {
+                        "name": "startOffset",
+                        "value": ""
+                      },
+                      {
+                        "name": "stdDeviation",
+                        "value": ""
+                      },
+                      {
+                        "name": "stitchTiles",
+                        "value": ""
+                      },
+                      {
+                        "name": "surfaceScale",
+                        "value": ""
+                      },
+                      {
+                        "name": "systemLanguage",
+                        "value": ""
+                      },
+                      {
+                        "name": "tableValues",
+                        "value": ""
+                      },
+                      {
+                        "name": "targetX",
+                        "value": ""
+                      },
+                      {
+                        "name": "targetY",
+                        "value": ""
+                      },
+                      {
+                        "name": "textLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "viewBox",
+                        "value": ""
+                      },
+                      {
+                        "name": "viewTarget",
+                        "value": ""
+                      },
+                      {
+                        "name": "xChannelSelector",
+                        "value": ""
+                      },
+                      {
+                        "name": "yChannelSelector",
+                        "value": ""
+                      },
+                      {
+                        "name": "zoomAndPan",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg attributeName=\"\" attributeType=\"\" baseFrequency=\"\" baseProfile=\"\" calcMode=\"\" clipPathUnits=\"\" diffuseConstant=\"\" edgeMode=\"\" filterUnits=\"\" glyphRef=\"\" gradientTransform=\"\" gradientUnits=\"\" kernelMatrix=\"\" kernelUnitLength=\"\" keyPoints=\"\" keySplines=\"\" keyTimes=\"\" lengthAdjust=\"\" limitingConeAngle=\"\" markerHeight=\"\" markerUnits=\"\" markerWidth=\"\" maskContentUnits=\"\" maskUnits=\"\" numOctaves=\"\" pathLength=\"\" patternContentUnits=\"\" patternTransform=\"\" patternUnits=\"\" pointsAtX=\"\" pointsAtY=\"\" pointsAtZ=\"\" preserveAlpha=\"\" preserveAspectRatio=\"\" primitiveUnits=\"\" refX=\"\" refY=\"\" repeatCount=\"\" repeatDur=\"\" requiredExtensions=\"\" requiredFeatures=\"\" specularConstant=\"\" specularExponent=\"\" spreadMethod=\"\" startOffset=\"\" stdDeviation=\"\" stitchTiles=\"\" surfaceScale=\"\" systemLanguage=\"\" tableValues=\"\" targetX=\"\" targetY=\"\" textLength=\"\" viewBox=\"\" viewTarget=\"\" xChannelSelector=\"\" yChannelSelector=\"\" zoomAndPan=\"\"></svg></body></html>",
+        "noQuirksBodyHtml": "<svg attributeName=\"\" attributeType=\"\" baseFrequency=\"\" baseProfile=\"\" calcMode=\"\" clipPathUnits=\"\" diffuseConstant=\"\" edgeMode=\"\" filterUnits=\"\" glyphRef=\"\" gradientTransform=\"\" gradientUnits=\"\" kernelMatrix=\"\" kernelUnitLength=\"\" keyPoints=\"\" keySplines=\"\" keyTimes=\"\" lengthAdjust=\"\" limitingConeAngle=\"\" markerHeight=\"\" markerUnits=\"\" markerWidth=\"\" maskContentUnits=\"\" maskUnits=\"\" numOctaves=\"\" pathLength=\"\" patternContentUnits=\"\" patternTransform=\"\" patternUnits=\"\" pointsAtX=\"\" pointsAtY=\"\" pointsAtZ=\"\" preserveAlpha=\"\" preserveAspectRatio=\"\" primitiveUnits=\"\" refX=\"\" refY=\"\" repeatCount=\"\" repeatDur=\"\" requiredExtensions=\"\" requiredFeatures=\"\" specularConstant=\"\" specularExponent=\"\" spreadMethod=\"\" startOffset=\"\" stdDeviation=\"\" stitchTiles=\"\" surfaceScale=\"\" systemLanguage=\"\" tableValues=\"\" targetX=\"\" targetY=\"\" textLength=\"\" viewBox=\"\" viewTarget=\"\" xChannelSelector=\"\" yChannelSelector=\"\" zoomAndPan=\"\"></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><svg attributename='' attributetype='' basefrequency='' baseprofile='' calcmode='' clippathunits='' diffuseconstant='' edgemode='' filterunits='' filterres='' glyphref='' gradienttransform='' gradientunits='' kernelmatrix='' kernelunitlength='' keypoints='' keysplines='' keytimes='' lengthadjust='' limitingconeangle='' markerheight='' markerunits='' markerwidth='' maskcontentunits='' maskunits='' numoctaves='' pathlength='' patterncontentunits='' patterntransform='' patternunits='' pointsatx='' pointsaty='' pointsatz='' preservealpha='' preserveaspectratio='' primitiveunits='' refx='' refy='' repeatcount='' repeatdur='' requiredextensions='' requiredfeatures='' specularconstant='' specularexponent='' spreadmethod='' startoffset='' stddeviation='' stitchtiles='' surfacescale='' systemlanguage='' tablevalues='' targetx='' targety='' textlength='' viewbox='' viewtarget='' xchannelselector='' ychannelselector='' zoomandpan=''></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "attrs": [
+                      {
+                        "name": "attributeName",
+                        "value": ""
+                      },
+                      {
+                        "name": "attributeType",
+                        "value": ""
+                      },
+                      {
+                        "name": "baseFrequency",
+                        "value": ""
+                      },
+                      {
+                        "name": "baseProfile",
+                        "value": ""
+                      },
+                      {
+                        "name": "calcMode",
+                        "value": ""
+                      },
+                      {
+                        "name": "clipPathUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "diffuseConstant",
+                        "value": ""
+                      },
+                      {
+                        "name": "edgeMode",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterres",
+                        "value": ""
+                      },
+                      {
+                        "name": "glyphRef",
+                        "value": ""
+                      },
+                      {
+                        "name": "gradientTransform",
+                        "value": ""
+                      },
+                      {
+                        "name": "gradientUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "kernelMatrix",
+                        "value": ""
+                      },
+                      {
+                        "name": "kernelUnitLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "keyPoints",
+                        "value": ""
+                      },
+                      {
+                        "name": "keySplines",
+                        "value": ""
+                      },
+                      {
+                        "name": "keyTimes",
+                        "value": ""
+                      },
+                      {
+                        "name": "lengthAdjust",
+                        "value": ""
+                      },
+                      {
+                        "name": "limitingConeAngle",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerHeight",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerWidth",
+                        "value": ""
+                      },
+                      {
+                        "name": "maskContentUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "maskUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "numOctaves",
+                        "value": ""
+                      },
+                      {
+                        "name": "pathLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternContentUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternTransform",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtX",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtY",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsAtZ",
+                        "value": ""
+                      },
+                      {
+                        "name": "preserveAlpha",
+                        "value": ""
+                      },
+                      {
+                        "name": "preserveAspectRatio",
+                        "value": ""
+                      },
+                      {
+                        "name": "primitiveUnits",
+                        "value": ""
+                      },
+                      {
+                        "name": "refX",
+                        "value": ""
+                      },
+                      {
+                        "name": "refY",
+                        "value": ""
+                      },
+                      {
+                        "name": "repeatCount",
+                        "value": ""
+                      },
+                      {
+                        "name": "repeatDur",
+                        "value": ""
+                      },
+                      {
+                        "name": "requiredExtensions",
+                        "value": ""
+                      },
+                      {
+                        "name": "requiredFeatures",
+                        "value": ""
+                      },
+                      {
+                        "name": "specularConstant",
+                        "value": ""
+                      },
+                      {
+                        "name": "specularExponent",
+                        "value": ""
+                      },
+                      {
+                        "name": "spreadMethod",
+                        "value": ""
+                      },
+                      {
+                        "name": "startOffset",
+                        "value": ""
+                      },
+                      {
+                        "name": "stdDeviation",
+                        "value": ""
+                      },
+                      {
+                        "name": "stitchTiles",
+                        "value": ""
+                      },
+                      {
+                        "name": "surfaceScale",
+                        "value": ""
+                      },
+                      {
+                        "name": "systemLanguage",
+                        "value": ""
+                      },
+                      {
+                        "name": "tableValues",
+                        "value": ""
+                      },
+                      {
+                        "name": "targetX",
+                        "value": ""
+                      },
+                      {
+                        "name": "targetY",
+                        "value": ""
+                      },
+                      {
+                        "name": "textLength",
+                        "value": ""
+                      },
+                      {
+                        "name": "viewBox",
+                        "value": ""
+                      },
+                      {
+                        "name": "viewTarget",
+                        "value": ""
+                      },
+                      {
+                        "name": "xChannelSelector",
+                        "value": ""
+                      },
+                      {
+                        "name": "yChannelSelector",
+                        "value": ""
+                      },
+                      {
+                        "name": "zoomAndPan",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg attributeName=\"\" attributeType=\"\" baseFrequency=\"\" baseProfile=\"\" calcMode=\"\" clipPathUnits=\"\" diffuseConstant=\"\" edgeMode=\"\" filterUnits=\"\" filterres=\"\" glyphRef=\"\" gradientTransform=\"\" gradientUnits=\"\" kernelMatrix=\"\" kernelUnitLength=\"\" keyPoints=\"\" keySplines=\"\" keyTimes=\"\" lengthAdjust=\"\" limitingConeAngle=\"\" markerHeight=\"\" markerUnits=\"\" markerWidth=\"\" maskContentUnits=\"\" maskUnits=\"\" numOctaves=\"\" pathLength=\"\" patternContentUnits=\"\" patternTransform=\"\" patternUnits=\"\" pointsAtX=\"\" pointsAtY=\"\" pointsAtZ=\"\" preserveAlpha=\"\" preserveAspectRatio=\"\" primitiveUnits=\"\" refX=\"\" refY=\"\" repeatCount=\"\" repeatDur=\"\" requiredExtensions=\"\" requiredFeatures=\"\" specularConstant=\"\" specularExponent=\"\" spreadMethod=\"\" startOffset=\"\" stdDeviation=\"\" stitchTiles=\"\" surfaceScale=\"\" systemLanguage=\"\" tableValues=\"\" targetX=\"\" targetY=\"\" textLength=\"\" viewBox=\"\" viewTarget=\"\" xChannelSelector=\"\" yChannelSelector=\"\" zoomAndPan=\"\"></svg></body></html>",
+        "noQuirksBodyHtml": "<svg attributeName=\"\" attributeType=\"\" baseFrequency=\"\" baseProfile=\"\" calcMode=\"\" clipPathUnits=\"\" diffuseConstant=\"\" edgeMode=\"\" filterUnits=\"\" filterres=\"\" glyphRef=\"\" gradientTransform=\"\" gradientUnits=\"\" kernelMatrix=\"\" kernelUnitLength=\"\" keyPoints=\"\" keySplines=\"\" keyTimes=\"\" lengthAdjust=\"\" limitingConeAngle=\"\" markerHeight=\"\" markerUnits=\"\" markerWidth=\"\" maskContentUnits=\"\" maskUnits=\"\" numOctaves=\"\" pathLength=\"\" patternContentUnits=\"\" patternTransform=\"\" patternUnits=\"\" pointsAtX=\"\" pointsAtY=\"\" pointsAtZ=\"\" preserveAlpha=\"\" preserveAspectRatio=\"\" primitiveUnits=\"\" refX=\"\" refY=\"\" repeatCount=\"\" repeatDur=\"\" requiredExtensions=\"\" requiredFeatures=\"\" specularConstant=\"\" specularExponent=\"\" spreadMethod=\"\" startOffset=\"\" stdDeviation=\"\" stitchTiles=\"\" surfaceScale=\"\" systemLanguage=\"\" tableValues=\"\" targetX=\"\" targetY=\"\" textLength=\"\" viewBox=\"\" viewTarget=\"\" xChannelSelector=\"\" yChannelSelector=\"\" zoomAndPan=\"\"></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><math attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' diffuseConstant='' edgeMode='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "attrs": [
+                      {
+                        "name": "attributename",
+                        "value": ""
+                      },
+                      {
+                        "name": "attributetype",
+                        "value": ""
+                      },
+                      {
+                        "name": "basefrequency",
+                        "value": ""
+                      },
+                      {
+                        "name": "baseprofile",
+                        "value": ""
+                      },
+                      {
+                        "name": "calcmode",
+                        "value": ""
+                      },
+                      {
+                        "name": "clippathunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "diffuseconstant",
+                        "value": ""
+                      },
+                      {
+                        "name": "edgemode",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "glyphref",
+                        "value": ""
+                      },
+                      {
+                        "name": "gradienttransform",
+                        "value": ""
+                      },
+                      {
+                        "name": "gradientunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "kernelmatrix",
+                        "value": ""
+                      },
+                      {
+                        "name": "kernelunitlength",
+                        "value": ""
+                      },
+                      {
+                        "name": "keypoints",
+                        "value": ""
+                      },
+                      {
+                        "name": "keysplines",
+                        "value": ""
+                      },
+                      {
+                        "name": "keytimes",
+                        "value": ""
+                      },
+                      {
+                        "name": "lengthadjust",
+                        "value": ""
+                      },
+                      {
+                        "name": "limitingconeangle",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerheight",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "markerwidth",
+                        "value": ""
+                      },
+                      {
+                        "name": "maskcontentunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "maskunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "numoctaves",
+                        "value": ""
+                      },
+                      {
+                        "name": "pathlength",
+                        "value": ""
+                      },
+                      {
+                        "name": "patterncontentunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "patterntransform",
+                        "value": ""
+                      },
+                      {
+                        "name": "patternunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsatx",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsaty",
+                        "value": ""
+                      },
+                      {
+                        "name": "pointsatz",
+                        "value": ""
+                      },
+                      {
+                        "name": "preservealpha",
+                        "value": ""
+                      },
+                      {
+                        "name": "preserveaspectratio",
+                        "value": ""
+                      },
+                      {
+                        "name": "primitiveunits",
+                        "value": ""
+                      },
+                      {
+                        "name": "refx",
+                        "value": ""
+                      },
+                      {
+                        "name": "refy",
+                        "value": ""
+                      },
+                      {
+                        "name": "repeatcount",
+                        "value": ""
+                      },
+                      {
+                        "name": "repeatdur",
+                        "value": ""
+                      },
+                      {
+                        "name": "requiredextensions",
+                        "value": ""
+                      },
+                      {
+                        "name": "requiredfeatures",
+                        "value": ""
+                      },
+                      {
+                        "name": "specularconstant",
+                        "value": ""
+                      },
+                      {
+                        "name": "specularexponent",
+                        "value": ""
+                      },
+                      {
+                        "name": "spreadmethod",
+                        "value": ""
+                      },
+                      {
+                        "name": "startoffset",
+                        "value": ""
+                      },
+                      {
+                        "name": "stddeviation",
+                        "value": ""
+                      },
+                      {
+                        "name": "stitchtiles",
+                        "value": ""
+                      },
+                      {
+                        "name": "surfacescale",
+                        "value": ""
+                      },
+                      {
+                        "name": "systemlanguage",
+                        "value": ""
+                      },
+                      {
+                        "name": "tablevalues",
+                        "value": ""
+                      },
+                      {
+                        "name": "targetx",
+                        "value": ""
+                      },
+                      {
+                        "name": "targety",
+                        "value": ""
+                      },
+                      {
+                        "name": "textlength",
+                        "value": ""
+                      },
+                      {
+                        "name": "viewbox",
+                        "value": ""
+                      },
+                      {
+                        "name": "viewtarget",
+                        "value": ""
+                      },
+                      {
+                        "name": "xchannelselector",
+                        "value": ""
+                      },
+                      {
+                        "name": "ychannelselector",
+                        "value": ""
+                      },
+                      {
+                        "name": "zoomandpan",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math attributename=\"\" attributetype=\"\" basefrequency=\"\" baseprofile=\"\" calcmode=\"\" clippathunits=\"\" diffuseconstant=\"\" edgemode=\"\" filterunits=\"\" glyphref=\"\" gradienttransform=\"\" gradientunits=\"\" kernelmatrix=\"\" kernelunitlength=\"\" keypoints=\"\" keysplines=\"\" keytimes=\"\" lengthadjust=\"\" limitingconeangle=\"\" markerheight=\"\" markerunits=\"\" markerwidth=\"\" maskcontentunits=\"\" maskunits=\"\" numoctaves=\"\" pathlength=\"\" patterncontentunits=\"\" patterntransform=\"\" patternunits=\"\" pointsatx=\"\" pointsaty=\"\" pointsatz=\"\" preservealpha=\"\" preserveaspectratio=\"\" primitiveunits=\"\" refx=\"\" refy=\"\" repeatcount=\"\" repeatdur=\"\" requiredextensions=\"\" requiredfeatures=\"\" specularconstant=\"\" specularexponent=\"\" spreadmethod=\"\" startoffset=\"\" stddeviation=\"\" stitchtiles=\"\" surfacescale=\"\" systemlanguage=\"\" tablevalues=\"\" targetx=\"\" targety=\"\" textlength=\"\" viewbox=\"\" viewtarget=\"\" xchannelselector=\"\" ychannelselector=\"\" zoomandpan=\"\"></math></body></html>",
+        "noQuirksBodyHtml": "<math attributename=\"\" attributetype=\"\" basefrequency=\"\" baseprofile=\"\" calcmode=\"\" clippathunits=\"\" diffuseconstant=\"\" edgemode=\"\" filterunits=\"\" glyphref=\"\" gradienttransform=\"\" gradientunits=\"\" kernelmatrix=\"\" kernelunitlength=\"\" keypoints=\"\" keysplines=\"\" keytimes=\"\" lengthadjust=\"\" limitingconeangle=\"\" markerheight=\"\" markerunits=\"\" markerwidth=\"\" maskcontentunits=\"\" maskunits=\"\" numoctaves=\"\" pathlength=\"\" patterncontentunits=\"\" patterntransform=\"\" patternunits=\"\" pointsatx=\"\" pointsaty=\"\" pointsatz=\"\" preservealpha=\"\" preserveaspectratio=\"\" primitiveunits=\"\" refx=\"\" refy=\"\" repeatcount=\"\" repeatdur=\"\" requiredextensions=\"\" requiredfeatures=\"\" specularconstant=\"\" specularexponent=\"\" spreadmethod=\"\" startoffset=\"\" stddeviation=\"\" stitchtiles=\"\" surfacescale=\"\" systemlanguage=\"\" tablevalues=\"\" targetx=\"\" targety=\"\" textlength=\"\" viewbox=\"\" viewtarget=\"\" xchannelselector=\"\" ychannelselector=\"\" zoomandpan=\"\"></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><svg><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg altGlyph": true,
+            "svg altGlyphDef": true,
+            "svg altGlyphItem": true,
+            "svg animateColor": true,
+            "svg animateMotion": true,
+            "svg animateTransform": true,
+            "svg clipPath": true,
+            "svg feBlend": true,
+            "svg feColorMatrix": true,
+            "svg feComponentTransfer": true,
+            "svg feComposite": true,
+            "svg feConvolveMatrix": true,
+            "svg feDiffuseLighting": true,
+            "svg feDisplacementMap": true,
+            "svg feDistantLight": true,
+            "svg feFlood": true,
+            "svg feFuncA": true,
+            "svg feFuncB": true,
+            "svg feFuncG": true,
+            "svg feFuncR": true,
+            "svg feGaussianBlur": true,
+            "svg feImage": true,
+            "svg feMerge": true,
+            "svg feMergeNode": true,
+            "svg feMorphology": true,
+            "svg feOffset": true,
+            "svg fePointLight": true,
+            "svg feSpecularLighting": true,
+            "svg feSpotLight": true,
+            "svg feTile": true,
+            "svg feTurbulence": true,
+            "svg foreignObject": true,
+            "svg glyphRef": true,
+            "svg linearGradient": true,
+            "svg radialGradient": true,
+            "svg textPath": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "altGlyph",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "altGlyphDef",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "altGlyphItem",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateColor",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateMotion",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateTransform",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "clipPath",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feBlend",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feColorMatrix",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feComponentTransfer",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feComposite",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feConvolveMatrix",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDiffuseLighting",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDisplacementMap",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDistantLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFlood",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncA",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncB",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncG",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncR",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feGaussianBlur",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feImage",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMerge",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMergeNode",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMorphology",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feOffset",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "fePointLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feSpecularLighting",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feSpotLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feTile",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feTurbulence",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "glyphRef",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "linearGradient",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "radialGradient",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "textPath",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><altGlyph></altGlyph><altGlyphDef></altGlyphDef><altGlyphItem></altGlyphItem><animateColor></animateColor><animateMotion></animateMotion><animateTransform></animateTransform><clipPath></clipPath><feBlend></feBlend><feColorMatrix></feColorMatrix><feComponentTransfer></feComponentTransfer><feComposite></feComposite><feConvolveMatrix></feConvolveMatrix><feDiffuseLighting></feDiffuseLighting><feDisplacementMap></feDisplacementMap><feDistantLight></feDistantLight><feFlood></feFlood><feFuncA></feFuncA><feFuncB></feFuncB><feFuncG></feFuncG><feFuncR></feFuncR><feGaussianBlur></feGaussianBlur><feImage></feImage><feMerge></feMerge><feMergeNode></feMergeNode><feMorphology></feMorphology><feOffset></feOffset><fePointLight></fePointLight><feSpecularLighting></feSpecularLighting><feSpotLight></feSpotLight><feTile></feTile><feTurbulence></feTurbulence><foreignObject></foreignObject><glyphRef></glyphRef><linearGradient></linearGradient><radialGradient></radialGradient><textPath></textPath></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><altGlyph></altGlyph><altGlyphDef></altGlyphDef><altGlyphItem></altGlyphItem><animateColor></animateColor><animateMotion></animateMotion><animateTransform></animateTransform><clipPath></clipPath><feBlend></feBlend><feColorMatrix></feColorMatrix><feComponentTransfer></feComponentTransfer><feComposite></feComposite><feConvolveMatrix></feConvolveMatrix><feDiffuseLighting></feDiffuseLighting><feDisplacementMap></feDisplacementMap><feDistantLight></feDistantLight><feFlood></feFlood><feFuncA></feFuncA><feFuncB></feFuncB><feFuncG></feFuncG><feFuncR></feFuncR><feGaussianBlur></feGaussianBlur><feImage></feImage><feMerge></feMerge><feMergeNode></feMergeNode><feMorphology></feMorphology><feOffset></feOffset><fePointLight></fePointLight><feSpecularLighting></feSpecularLighting><feSpotLight></feSpotLight><feTile></feTile><feTurbulence></feTurbulence><foreignObject></foreignObject><glyphRef></glyphRef><linearGradient></linearGradient><radialGradient></radialGradient><textPath></textPath></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><svg><altglyph /><altglyphdef /><altglyphitem /><animatecolor /><animatemotion /><animatetransform /><clippath /><feblend /><fecolormatrix /><fecomponenttransfer /><fecomposite /><feconvolvematrix /><fediffuselighting /><fedisplacementmap /><fedistantlight /><feflood /><fefunca /><fefuncb /><fefuncg /><fefuncr /><fegaussianblur /><feimage /><femerge /><femergenode /><femorphology /><feoffset /><fepointlight /><fespecularlighting /><fespotlight /><fetile /><feturbulence /><foreignobject /><glyphref /><lineargradient /><radialgradient /><textpath /></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg altGlyph": true,
+            "svg altGlyphDef": true,
+            "svg altGlyphItem": true,
+            "svg animateColor": true,
+            "svg animateMotion": true,
+            "svg animateTransform": true,
+            "svg clipPath": true,
+            "svg feBlend": true,
+            "svg feColorMatrix": true,
+            "svg feComponentTransfer": true,
+            "svg feComposite": true,
+            "svg feConvolveMatrix": true,
+            "svg feDiffuseLighting": true,
+            "svg feDisplacementMap": true,
+            "svg feDistantLight": true,
+            "svg feFlood": true,
+            "svg feFuncA": true,
+            "svg feFuncB": true,
+            "svg feFuncG": true,
+            "svg feFuncR": true,
+            "svg feGaussianBlur": true,
+            "svg feImage": true,
+            "svg feMerge": true,
+            "svg feMergeNode": true,
+            "svg feMorphology": true,
+            "svg feOffset": true,
+            "svg fePointLight": true,
+            "svg feSpecularLighting": true,
+            "svg feSpotLight": true,
+            "svg feTile": true,
+            "svg feTurbulence": true,
+            "svg foreignObject": true,
+            "svg glyphRef": true,
+            "svg linearGradient": true,
+            "svg radialGradient": true,
+            "svg textPath": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "altGlyph",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "altGlyphDef",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "altGlyphItem",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateColor",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateMotion",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateTransform",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "clipPath",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feBlend",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feColorMatrix",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feComponentTransfer",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feComposite",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feConvolveMatrix",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDiffuseLighting",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDisplacementMap",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDistantLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFlood",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncA",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncB",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncG",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncR",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feGaussianBlur",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feImage",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMerge",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMergeNode",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMorphology",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feOffset",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "fePointLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feSpecularLighting",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feSpotLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feTile",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feTurbulence",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "glyphRef",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "linearGradient",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "radialGradient",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "textPath",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><altGlyph></altGlyph><altGlyphDef></altGlyphDef><altGlyphItem></altGlyphItem><animateColor></animateColor><animateMotion></animateMotion><animateTransform></animateTransform><clipPath></clipPath><feBlend></feBlend><feColorMatrix></feColorMatrix><feComponentTransfer></feComponentTransfer><feComposite></feComposite><feConvolveMatrix></feConvolveMatrix><feDiffuseLighting></feDiffuseLighting><feDisplacementMap></feDisplacementMap><feDistantLight></feDistantLight><feFlood></feFlood><feFuncA></feFuncA><feFuncB></feFuncB><feFuncG></feFuncG><feFuncR></feFuncR><feGaussianBlur></feGaussianBlur><feImage></feImage><feMerge></feMerge><feMergeNode></feMergeNode><feMorphology></feMorphology><feOffset></feOffset><fePointLight></fePointLight><feSpecularLighting></feSpecularLighting><feSpotLight></feSpotLight><feTile></feTile><feTurbulence></feTurbulence><foreignObject></foreignObject><glyphRef></glyphRef><linearGradient></linearGradient><radialGradient></radialGradient><textPath></textPath></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><altGlyph></altGlyph><altGlyphDef></altGlyphDef><altGlyphItem></altGlyphItem><animateColor></animateColor><animateMotion></animateMotion><animateTransform></animateTransform><clipPath></clipPath><feBlend></feBlend><feColorMatrix></feColorMatrix><feComponentTransfer></feComponentTransfer><feComposite></feComposite><feConvolveMatrix></feConvolveMatrix><feDiffuseLighting></feDiffuseLighting><feDisplacementMap></feDisplacementMap><feDistantLight></feDistantLight><feFlood></feFlood><feFuncA></feFuncA><feFuncB></feFuncB><feFuncG></feFuncG><feFuncR></feFuncR><feGaussianBlur></feGaussianBlur><feImage></feImage><feMerge></feMerge><feMergeNode></feMergeNode><feMorphology></feMorphology><feOffset></feOffset><fePointLight></fePointLight><feSpecularLighting></feSpecularLighting><feSpotLight></feSpotLight><feTile></feTile><feTurbulence></feTurbulence><foreignObject></foreignObject><glyphRef></glyphRef><linearGradient></linearGradient><radialGradient></radialGradient><textPath></textPath></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><BODY><SVG><ALTGLYPH /><ALTGLYPHDEF /><ALTGLYPHITEM /><ANIMATECOLOR /><ANIMATEMOTION /><ANIMATETRANSFORM /><CLIPPATH /><FEBLEND /><FECOLORMATRIX /><FECOMPONENTTRANSFER /><FECOMPOSITE /><FECONVOLVEMATRIX /><FEDIFFUSELIGHTING /><FEDISPLACEMENTMAP /><FEDISTANTLIGHT /><FEFLOOD /><FEFUNCA /><FEFUNCB /><FEFUNCG /><FEFUNCR /><FEGAUSSIANBLUR /><FEIMAGE /><FEMERGE /><FEMERGENODE /><FEMORPHOLOGY /><FEOFFSET /><FEPOINTLIGHT /><FESPECULARLIGHTING /><FESPOTLIGHT /><FETILE /><FETURBULENCE /><FOREIGNOBJECT /><GLYPHREF /><LINEARGRADIENT /><RADIALGRADIENT /><TEXTPATH /></SVG>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg altGlyph": true,
+            "svg altGlyphDef": true,
+            "svg altGlyphItem": true,
+            "svg animateColor": true,
+            "svg animateMotion": true,
+            "svg animateTransform": true,
+            "svg clipPath": true,
+            "svg feBlend": true,
+            "svg feColorMatrix": true,
+            "svg feComponentTransfer": true,
+            "svg feComposite": true,
+            "svg feConvolveMatrix": true,
+            "svg feDiffuseLighting": true,
+            "svg feDisplacementMap": true,
+            "svg feDistantLight": true,
+            "svg feFlood": true,
+            "svg feFuncA": true,
+            "svg feFuncB": true,
+            "svg feFuncG": true,
+            "svg feFuncR": true,
+            "svg feGaussianBlur": true,
+            "svg feImage": true,
+            "svg feMerge": true,
+            "svg feMergeNode": true,
+            "svg feMorphology": true,
+            "svg feOffset": true,
+            "svg fePointLight": true,
+            "svg feSpecularLighting": true,
+            "svg feSpotLight": true,
+            "svg feTile": true,
+            "svg feTurbulence": true,
+            "svg foreignObject": true,
+            "svg glyphRef": true,
+            "svg linearGradient": true,
+            "svg radialGradient": true,
+            "svg textPath": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "altGlyph",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "altGlyphDef",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "altGlyphItem",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateColor",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateMotion",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "animateTransform",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "clipPath",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feBlend",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feColorMatrix",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feComponentTransfer",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feComposite",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feConvolveMatrix",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDiffuseLighting",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDisplacementMap",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feDistantLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFlood",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncA",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncB",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncG",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feFuncR",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feGaussianBlur",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feImage",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMerge",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMergeNode",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feMorphology",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feOffset",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "fePointLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feSpecularLighting",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feSpotLight",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feTile",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "feTurbulence",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "glyphRef",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "linearGradient",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "radialGradient",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "textPath",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><altGlyph></altGlyph><altGlyphDef></altGlyphDef><altGlyphItem></altGlyphItem><animateColor></animateColor><animateMotion></animateMotion><animateTransform></animateTransform><clipPath></clipPath><feBlend></feBlend><feColorMatrix></feColorMatrix><feComponentTransfer></feComponentTransfer><feComposite></feComposite><feConvolveMatrix></feConvolveMatrix><feDiffuseLighting></feDiffuseLighting><feDisplacementMap></feDisplacementMap><feDistantLight></feDistantLight><feFlood></feFlood><feFuncA></feFuncA><feFuncB></feFuncB><feFuncG></feFuncG><feFuncR></feFuncR><feGaussianBlur></feGaussianBlur><feImage></feImage><feMerge></feMerge><feMergeNode></feMergeNode><feMorphology></feMorphology><feOffset></feOffset><fePointLight></fePointLight><feSpecularLighting></feSpecularLighting><feSpotLight></feSpotLight><feTile></feTile><feTurbulence></feTurbulence><foreignObject></foreignObject><glyphRef></glyphRef><linearGradient></linearGradient><radialGradient></radialGradient><textPath></textPath></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><altGlyph></altGlyph><altGlyphDef></altGlyphDef><altGlyphItem></altGlyphItem><animateColor></animateColor><animateMotion></animateMotion><animateTransform></animateTransform><clipPath></clipPath><feBlend></feBlend><feColorMatrix></feColorMatrix><feComponentTransfer></feComponentTransfer><feComposite></feComposite><feConvolveMatrix></feConvolveMatrix><feDiffuseLighting></feDiffuseLighting><feDisplacementMap></feDisplacementMap><feDistantLight></feDistantLight><feFlood></feFlood><feFuncA></feFuncA><feFuncB></feFuncB><feFuncG></feFuncG><feFuncR></feFuncR><feGaussianBlur></feGaussianBlur><feImage></feImage><feMerge></feMerge><feMergeNode></feMergeNode><feMorphology></feMorphology><feOffset></feOffset><fePointLight></fePointLight><feSpecularLighting></feSpecularLighting><feSpotLight></feSpotLight><feTile></feTile><feTurbulence></feTurbulence><foreignObject></foreignObject><glyphRef></glyphRef><linearGradient></linearGradient><radialGradient></radialGradient><textPath></textPath></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><math><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math altglyph": true,
+            "math altglyphdef": true,
+            "math altglyphitem": true,
+            "math animatecolor": true,
+            "math animatemotion": true,
+            "math animatetransform": true,
+            "math clippath": true,
+            "math feblend": true,
+            "math fecolormatrix": true,
+            "math fecomponenttransfer": true,
+            "math fecomposite": true,
+            "math feconvolvematrix": true,
+            "math fediffuselighting": true,
+            "math fedisplacementmap": true,
+            "math fedistantlight": true,
+            "math feflood": true,
+            "math fefunca": true,
+            "math fefuncb": true,
+            "math fefuncg": true,
+            "math fefuncr": true,
+            "math fegaussianblur": true,
+            "math feimage": true,
+            "math femerge": true,
+            "math femergenode": true,
+            "math femorphology": true,
+            "math feoffset": true,
+            "math fepointlight": true,
+            "math fespecularlighting": true,
+            "math fespotlight": true,
+            "math fetile": true,
+            "math feturbulence": true,
+            "math foreignobject": true,
+            "math glyphref": true,
+            "math lineargradient": true,
+            "math radialgradient": true,
+            "math textpath": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "altglyph",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "altglyphdef",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "altglyphitem",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "animatecolor",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "animatemotion",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "animatetransform",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "clippath",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "feblend",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fecolormatrix",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fecomponenttransfer",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fecomposite",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "feconvolvematrix",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fediffuselighting",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fedisplacementmap",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fedistantlight",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "feflood",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fefunca",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fefuncb",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fefuncg",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fefuncr",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fegaussianblur",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "feimage",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "femerge",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "femergenode",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "femorphology",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "feoffset",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fepointlight",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fespecularlighting",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fespotlight",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "fetile",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "feturbulence",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "foreignobject",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "glyphref",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "lineargradient",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "radialgradient",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      },
+                      {
+                        "tag": "textpath",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><altglyph></altglyph><altglyphdef></altglyphdef><altglyphitem></altglyphitem><animatecolor></animatecolor><animatemotion></animatemotion><animatetransform></animatetransform><clippath></clippath><feblend></feblend><fecolormatrix></fecolormatrix><fecomponenttransfer></fecomponenttransfer><fecomposite></fecomposite><feconvolvematrix></feconvolvematrix><fediffuselighting></fediffuselighting><fedisplacementmap></fedisplacementmap><fedistantlight></fedistantlight><feflood></feflood><fefunca></fefunca><fefuncb></fefuncb><fefuncg></fefuncg><fefuncr></fefuncr><fegaussianblur></fegaussianblur><feimage></feimage><femerge></femerge><femergenode></femergenode><femorphology></femorphology><feoffset></feoffset><fepointlight></fepointlight><fespecularlighting></fespecularlighting><fespotlight></fespotlight><fetile></fetile><feturbulence></feturbulence><foreignobject></foreignobject><glyphref></glyphref><lineargradient></lineargradient><radialgradient></radialgradient><textpath></textpath></math></body></html>",
+        "noQuirksBodyHtml": "<math><altglyph></altglyph><altglyphdef></altglyphdef><altglyphitem></altglyphitem><animatecolor></animatecolor><animatemotion></animatemotion><animatetransform></animatetransform><clippath></clippath><feblend></feblend><fecolormatrix></fecolormatrix><fecomponenttransfer></fecomponenttransfer><fecomposite></fecomposite><feconvolvematrix></feconvolvematrix><fediffuselighting></fediffuselighting><fedisplacementmap></fedisplacementmap><fedistantlight></fedistantlight><feflood></feflood><fefunca></fefunca><fefuncb></fefuncb><fefuncg></fefuncg><fefuncr></fefuncr><fegaussianblur></fegaussianblur><feimage></feimage><femerge></femerge><femergenode></femergenode><femorphology></femorphology><feoffset></feoffset><fepointlight></fepointlight><fespecularlighting></fespecularlighting><fespotlight></fespotlight><fetile></fetile><feturbulence></feturbulence><foreignobject></foreignobject><glyphref></glyphref><lineargradient></lineargradient><radialgradient></radialgradient><textpath></textpath></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><svg><solidColor /></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg solidcolor": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "solidcolor",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><solidcolor></solidcolor></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><solidcolor></solidcolor></svg>"
+      }
+    }
+  ],
+  "tests12.dat": [
+    {
+      "data": "<!DOCTYPE html><body><p>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><P>spam<TABLE><tr><td><img></td></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "math math": true,
+            "math mtext": true,
+            "i": true,
+            "math annotation-xml": true,
+            "svg svg": true,
+            "svg desc": true,
+            "b": true,
+            "svg g": true,
+            "svg foreignObject": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "img": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "foo"
+                      },
+                      {
+                        "tag": "math",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mtext",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "i",
+                                "children": [
+                                  {
+                                    "text": "baz"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "annotation-xml",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "svg",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "desc",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "b",
+                                        "children": [
+                                          {
+                                            "text": "eggs"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "tag": "g",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "foreignObject",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "tag": "p",
+                                            "children": [
+                                              {
+                                                "text": "spam"
+                                              }
+                                            ]
+                                          },
+                                          {
+                                            "tag": "table",
+                                            "children": [
+                                              {
+                                                "tag": "tbody",
+                                                "children": [
+                                                  {
+                                                    "tag": "tr",
+                                                    "children": [
+                                                      {
+                                                        "tag": "td",
+                                                        "children": [
+                                                          {
+                                                            "tag": "img"
+                                                          }
+                                                        ]
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "tag": "g",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "text": "quux"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "text": "bar"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><p>spam</p><table><tbody><tr><td><img></td></tr></tbody></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar</p></body></html>",
+        "noQuirksBodyHtml": "<p>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><p>spam</p><table><tbody><tr><td><img></td></tr></tbody></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><P>spam<TABLE><tr><td><img></td></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mtext": true,
+            "i": true,
+            "math annotation-xml": true,
+            "svg svg": true,
+            "svg desc": true,
+            "b": true,
+            "svg g": true,
+            "svg foreignObject": true,
+            "p": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "img": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "foo"
+                  },
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mtext",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "baz"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "desc",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "b",
+                                    "children": [
+                                      {
+                                        "text": "eggs"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "g",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "foreignObject",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "p",
+                                        "children": [
+                                          {
+                                            "text": "spam"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "table",
+                                        "children": [
+                                          {
+                                            "tag": "tbody",
+                                            "children": [
+                                              {
+                                                "tag": "tr",
+                                                "children": [
+                                                  {
+                                                    "tag": "td",
+                                                    "children": [
+                                                      {
+                                                        "tag": "img"
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "g",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "text": "quux"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "bar"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><p>spam</p><table><tbody><tr><td><img></td></tr></tbody></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar</body></html>",
+        "noQuirksBodyHtml": "foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><p>spam</p><table><tbody><tr><td><img></td></tr></tbody></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar"
+      }
+    }
+  ],
+  "tests14.dat": [
+    {
+      "data": "<!DOCTYPE html><html><body><xyz:abc></xyz:abc>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "xyz:abc": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "xyz:abc"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><xyz:abc></xyz:abc></body></html>",
+        "noQuirksBodyHtml": "<xyz:abc></xyz:abc>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><body><xyz:abc></xyz:abc><span></span>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "xyz:abc": true,
+            "span": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "xyz:abc"
+                  },
+                  {
+                    "tag": "span"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><xyz:abc></xyz:abc><span></span></body></html>",
+        "noQuirksBodyHtml": "<xyz:abc></xyz:abc><span></span>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><html abc:def=gh><xyz:abc></xyz:abc>",
+      "errors": [
+        "(1,38): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "xyz:abc": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "abc:def",
+                "value": "gh"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "xyz:abc"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html abc:def=\"gh\"><head></head><body><xyz:abc></xyz:abc></body></html>",
+        "noQuirksBodyHtml": "<xyz:abc></xyz:abc>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html xml:lang=bar><html xml:lang=foo>",
+      "errors": [
+        "(1,53): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "xml:lang",
+                "value": "bar"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html xml:lang=\"bar\"><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html 123=456>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "123",
+                "value": "456"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html 123=\"456\"><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html 123=456><html 789=012>",
+      "errors": [
+        "(1,43): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "123",
+                "value": "456"
+              },
+              {
+                "name": "789",
+                "value": "012"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html 123=\"456\" 789=\"012\"><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><body 789=012>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "789",
+                    "value": "012"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body 789=\"012\"></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    }
+  ],
+  "tests15.dat": [
+    {
+      "data": "<!DOCTYPE html><p><b><i><u></p> <p>X",
+      "errors": [
+        "(1,31): unexpected-end-tag",
+        "(1,36): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "b": true,
+            "i": true,
+            "u": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "u"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "tag": "u",
+                            "children": [
+                              {
+                                "text": " "
+                              },
+                              {
+                                "tag": "p",
+                                "children": [
+                                  {
+                                    "text": "X"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><b><i><u></u></i></b></p><b><i><u> <p>X</p></u></i></b></body></html>",
+        "noQuirksBodyHtml": "<p><b><i><u></u></i></b></p><b><i><u> <p>X</p></u></i></b>"
+      }
+    },
+    {
+      "data": "<p><b><i><u></p>\n<p>X",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,16): unexpected-end-tag",
+        "(2,4): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "b": true,
+            "i": true,
+            "u": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "u"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "tag": "u",
+                            "children": [
+                              {
+                                "text": "\n"
+                              },
+                              {
+                                "tag": "p",
+                                "children": [
+                                  {
+                                    "text": "X"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><b><i><u></u></i></b></p><b><i><u>\n<p>X</p></u></i></b></body></html>",
+        "noQuirksBodyHtml": "<p><b><i><u></u></i></b></p><b><i><u>\n<p>X</p></u></i></b>"
+      }
+    },
+    {
+      "data": "<!doctype html></html> <head>",
+      "errors": [
+        "(1,29): expected-eof-but-got-start-tag",
+        "(1,29): unexpected-start-tag-ignored"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": " "
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body> </body></html>",
+        "noQuirksBodyHtml": " "
+      }
+    },
+    {
+      "data": "<!doctype html></body><meta>",
+      "errors": [
+        "(1,28): unexpected-start-tag-after-body"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "meta": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "meta"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><meta></body></html>",
+        "noQuirksBodyHtml": "<meta>"
+      }
+    },
+    {
+      "data": "<html></html><!-- foo -->",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          },
+          {
+            "comment": " foo "
+          }
+        ],
+        "html": "<html><head></head><body></body></html><!-- foo -->",
+        "noQuirksBodyHtml": "<!-- foo -->"
+      }
+    },
+    {
+      "data": "<!doctype html></body><title>X</title>",
+      "errors": [
+        "(1,29): unexpected-start-tag-after-body"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "title": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><title>X</title></body></html>",
+        "noQuirksBodyHtml": "<title>X</title>"
+      }
+    },
+    {
+      "data": "<!doctype html><table> X<meta></table>",
+      "errors": [
+        "(1,23): foster-parenting-character",
+        "(1,24): foster-parenting-character",
+        "(1,30): foster-parenting-start-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "meta": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": " X"
+                  },
+                  {
+                    "tag": "meta"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body> X<meta><table></table></body></html>",
+        "noQuirksBodyHtml": " X<meta><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table> x</table>",
+      "errors": [
+        "(1,23): foster-parenting-character",
+        "(1,24): foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": " x"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body> x<table></table></body></html>",
+        "noQuirksBodyHtml": " x<table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table> x </table>",
+      "errors": [
+        "(1,23): foster-parenting-character",
+        "(1,24): foster-parenting-character",
+        "(1,25): foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": " x "
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body> x <table></table></body></html>",
+        "noQuirksBodyHtml": " x <table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr> x</table>",
+      "errors": [
+        "(1,27): foster-parenting-character",
+        "(1,28): foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": " x"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body> x<table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": " x<table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table>X<style> <tr>x </style> </table>",
+      "errors": [
+        "(1,23): foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "style": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "style",
+                        "children": [
+                          {
+                            "text": " <tr>x ",
+                            "no_escape": true
+                          }
+                        ]
+                      },
+                      {
+                        "text": " "
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>X<table><style> <tr>x </style> </table></body></html>",
+        "noQuirksBodyHtml": "X<table><style> <tr>x </style> </table>"
+      }
+    },
+    {
+      "data": "<!doctype html><div><table><a>foo</a> <tr><td>bar</td> </tr></table></div>",
+      "errors": [
+        "(1,30): foster-parenting-start-tag",
+        "(1,31): foster-parenting-character",
+        "(1,32): foster-parenting-character",
+        "(1,33): foster-parenting-character",
+        "(1,37): foster-parenting-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "text": " "
+                          },
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr",
+                                "children": [
+                                  {
+                                    "tag": "td",
+                                    "children": [
+                                      {
+                                        "text": "bar"
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "text": " "
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><div><a>foo</a><table> <tbody><tr><td>bar</td> </tr></tbody></table></div></body></html>",
+        "noQuirksBodyHtml": "<div><a>foo</a><table> <tbody><tr><td>bar</td> </tr></tbody></table></div>"
+      }
+    },
+    {
+      "data": "<frame></frame></frame><frameset><frame><frameset><frame></frameset><noframes></frameset><noframes>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,7): unexpected-start-tag-ignored",
+        "(1,15): unexpected-end-tag",
+        "(1,23): unexpected-end-tag",
+        "(1,33): unexpected-start-tag",
+        "(1,99): expected-named-closing-tag-but-got-eof",
+        "(1,99): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true,
+            "noframes": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  },
+                  {
+                    "tag": "frameset",
+                    "children": [
+                      {
+                        "tag": "frame"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "noframes",
+                    "children": [
+                      {
+                        "text": "</frameset><noframes>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset><frame><frameset><frame></frameset><noframes></frameset><noframes></noframes></frameset></html>",
+        "noQuirksBodyHtml": "<noframes></frameset><noframes></noframes>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><object></html>",
+      "errors": [
+        "(1,30): expected-body-in-scope",
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "object": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "object"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><object></object></body></html>",
+        "noQuirksBodyHtml": "<object></object>"
+      }
+    }
+  ],
+  "tests16.dat": [
+    {
+      "data": "<!doctype html><script>",
+      "errors": [
+        "(1,23): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script>a",
+      "errors": [
+        "(1,24): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script>a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script>a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><",
+      "errors": [
+        "(1,24): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></",
+      "errors": [
+        "(1,25): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></S",
+      "errors": [
+        "(1,26): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</S",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></S</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></S</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></SC",
+      "errors": [
+        "(1,27): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SC",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></SC</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SC</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></SCR",
+      "errors": [
+        "(1,28): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SCR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></SCR</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SCR</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></SCRI",
+      "errors": [
+        "(1,29): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SCRI",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></SCRI</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SCRI</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></SCRIP",
+      "errors": [
+        "(1,30): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SCRIP",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></SCRIP</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SCRIP</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></SCRIPT",
+      "errors": [
+        "(1,31): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SCRIPT",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></SCRIPT</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SCRIPT</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></SCRIPT ",
+      "errors": [
+        "(1,32): expected-attribute-name-but-got-eof",
+        "(1,32): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></s",
+      "errors": [
+        "(1,26): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</s",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></s</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></s</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></sc",
+      "errors": [
+        "(1,27): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</sc",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></sc</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></sc</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></scr",
+      "errors": [
+        "(1,28): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</scr",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></scr</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></scr</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></scri",
+      "errors": [
+        "(1,29): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</scri",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></scri</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></scri</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></scrip",
+      "errors": [
+        "(1,30): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</scrip",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></scrip</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></scrip</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></script",
+      "errors": [
+        "(1,31): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script></script ",
+      "errors": [
+        "(1,32): expected-attribute-name-but-got-eof",
+        "(1,32): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!",
+      "errors": [
+        "(1,25): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!a",
+      "errors": [
+        "(1,26): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!-",
+      "errors": [
+        "(1,26): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!-",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!-</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!-</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!-a",
+      "errors": [
+        "(1,27): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!-a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!-a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!-a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--",
+      "errors": [
+        "(1,27): expected-named-closing-tag-but-got-eof",
+        "(1,27): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--a",
+      "errors": [
+        "(1,28): expected-named-closing-tag-but-got-eof",
+        "(1,28): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<",
+      "errors": [
+        "(1,28): expected-named-closing-tag-but-got-eof",
+        "(1,28): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<a",
+      "errors": [
+        "(1,29): expected-named-closing-tag-but-got-eof",
+        "(1,29): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--</",
+      "errors": [
+        "(1,29): expected-named-closing-tag-but-got-eof",
+        "(1,29): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--</",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--</</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--</</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--</script",
+      "errors": [
+        "(1,35): expected-named-closing-tag-but-got-eof",
+        "(1,35): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--</script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--</script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--</script</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--</script ",
+      "errors": [
+        "(1,36): expected-attribute-name-but-got-eof",
+        "(1,36): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<s",
+      "errors": [
+        "(1,29): expected-named-closing-tag-but-got-eof",
+        "(1,29): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<s",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<s</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<s</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script",
+      "errors": [
+        "(1,34): expected-named-closing-tag-but-got-eof",
+        "(1,34): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script ",
+      "errors": [
+        "(1,35): eof-in-script-in-script",
+        "(1,35): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script <",
+      "errors": [
+        "(1,36): eof-in-script-in-script",
+        "(1,36): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script <",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script <</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script <</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script <a",
+      "errors": [
+        "(1,37): eof-in-script-in-script",
+        "(1,37): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script <a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script <a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script <a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </",
+      "errors": [
+        "(1,37): eof-in-script-in-script",
+        "(1,37): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </s",
+      "errors": [
+        "(1,38): eof-in-script-in-script",
+        "(1,38): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </s",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </s</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </s</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script",
+      "errors": [
+        "(1,43): eof-in-script-in-script",
+        "(1,43): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </scripta",
+      "errors": [
+        "(1,44): eof-in-script-in-script",
+        "(1,44): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </scripta",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </scripta</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </scripta</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script ",
+      "errors": [
+        "(1,44): expected-named-closing-tag-but-got-eof",
+        "(1,44): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script>",
+      "errors": [
+        "(1,44): expected-named-closing-tag-but-got-eof",
+        "(1,44): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script/",
+      "errors": [
+        "(1,44): expected-named-closing-tag-but-got-eof",
+        "(1,44): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script/",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script/</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script/</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script <",
+      "errors": [
+        "(1,45): expected-named-closing-tag-but-got-eof",
+        "(1,45): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script <",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script <</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script <</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script <a",
+      "errors": [
+        "(1,46): expected-named-closing-tag-but-got-eof",
+        "(1,46): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script <a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script <a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script <a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script </",
+      "errors": [
+        "(1,46): expected-named-closing-tag-but-got-eof",
+        "(1,46): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script </",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script </</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script </script",
+      "errors": [
+        "(1,52): expected-named-closing-tag-but-got-eof",
+        "(1,52): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script </script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script </script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script </script ",
+      "errors": [
+        "(1,53): expected-attribute-name-but-got-eof",
+        "(1,53): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script </script/",
+      "errors": [
+        "(1,53): unexpected-EOF-after-solidus-in-tag",
+        "(1,53): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script </script </script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script </script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script -",
+      "errors": [
+        "(1,36): eof-in-script-in-script",
+        "(1,36): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script -</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script -</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script -a",
+      "errors": [
+        "(1,37): eof-in-script-in-script",
+        "(1,37): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script -a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script -a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script -<",
+      "errors": [
+        "(1,37): eof-in-script-in-script",
+        "(1,37): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -<",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script -<</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script -<</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --",
+      "errors": [
+        "(1,37): eof-in-script-in-script",
+        "(1,37): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --a",
+      "errors": [
+        "(1,38): eof-in-script-in-script",
+        "(1,38): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --a</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --<",
+      "errors": [
+        "(1,38): eof-in-script-in-script",
+        "(1,38): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --<",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --<</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --<</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script -->",
+      "errors": [
+        "(1,38): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --><",
+      "errors": [
+        "(1,39): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --><",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --><</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --><</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --></",
+      "errors": [
+        "(1,40): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --></",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --></</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --></script",
+      "errors": [
+        "(1,46): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --></script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --></script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --></script ",
+      "errors": [
+        "(1,47): expected-attribute-name-but-got-eof",
+        "(1,47): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --></script/",
+      "errors": [
+        "(1,47): unexpected-EOF-after-solidus-in-tag",
+        "(1,47): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script --></script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script --></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script><\\/script>--></script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script><\\/script>-->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script><\\/script>--></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script><\\/script>--></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script></scr'+'ipt>--></script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></scr'+'ipt>-->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script></scr'+'ipt>--></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></scr'+'ipt>--></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script></script><script></script></script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script></script><script></script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script></script><script></script>--><!--</script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>--><!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script></script><script></script>--><!--</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>--><!--</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script></script><script></script>-- ></script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>-- >",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script></script><script></script>-- ></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>-- ></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script></script><script></script>- -></script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>- ->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script></script><script></script>- -></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>- -></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script></script><script></script>- - ></script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>- - >",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script></script><script></script>- - ></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>- - ></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script></script><script></script>-></script>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script></script><script></script>-></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>-></script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script>--!></script>X",
+      "errors": [
+        "(1,49): expected-named-closing-tag-but-got-eof",
+        "(1,49): unexpected-EOF-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script>--!></script>X",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script>--!></script>X</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script>--!></script>X</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<scr'+'ipt></script>--></script>",
+      "errors": [
+        "(1,59): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<scr'+'ipt>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<scr'+'ipt></script></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<script><!--<scr'+'ipt></script>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><script><!--<script></scr'+'ipt></script>X",
+      "errors": [
+        "(1,57): expected-named-closing-tag-but-got-eof",
+        "(1,57): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></scr'+'ipt></script>X",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script><!--<script></scr'+'ipt></script>X</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></scr'+'ipt></script>X</script>"
+      }
+    },
+    {
+      "data": "<!doctype html><style><!--<style></style>--></style>",
+      "errors": [
+        "(1,52): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--<style>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style><!--<style></style></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<style><!--<style></style>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><style><!--</style>X",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style><!--</style></head><body>X</body></html>",
+        "noQuirksBodyHtml": "<style><!--</style>X"
+      }
+    },
+    {
+      "data": "<!doctype html><style><!--...</style>...--></style>",
+      "errors": [
+        "(1,51): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--...",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "...-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style><!--...</style></head><body>...--&gt;</body></html>",
+        "noQuirksBodyHtml": "<style><!--...</style>...--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><style><!--<br><html xmlns:v=\"urn:schemas-microsoft-com:vml\"><!--[if !mso]><style></style>X",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--<br><html xmlns:v=\"urn:schemas-microsoft-com:vml\"><!--[if !mso]><style>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style><!--<br><html xmlns:v=\"urn:schemas-microsoft-com:vml\"><!--[if !mso]><style></style></head><body>X</body></html>",
+        "noQuirksBodyHtml": "<style><!--<br><html xmlns:v=\"urn:schemas-microsoft-com:vml\"><!--[if !mso]><style></style>X"
+      }
+    },
+    {
+      "data": "<!doctype html><style><!--...<style><!--...--!></style>--></style>",
+      "errors": [
+        "(1,66): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--...<style><!--...--!>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style><!--...<style><!--...--!></style></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<style><!--...<style><!--...--!></style>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><style><!--...</style><!-- --><style>@import ...</style>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--...",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "comment": " "
+                  },
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "@import ...",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style><!--...</style><!-- --><style>@import ...</style></head><body></body></html>",
+        "noQuirksBodyHtml": "<style><!--...</style><!-- --><style>@import ...</style>"
+      }
+    },
+    {
+      "data": "<!doctype html><style>...<style><!--...</style><!-- --></style>",
+      "errors": [
+        "(1,63): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "...<style><!--...",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "comment": " "
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style>...<style><!--...</style><!-- --></head><body></body></html>",
+        "noQuirksBodyHtml": "<style>...<style><!--...</style><!-- -->"
+      }
+    },
+    {
+      "data": "<!doctype html><style>...<!--[if IE]><style>...</style>X",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "...<!--[if IE]><style>...",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><style>...<!--[if IE]><style>...</style></head><body>X</body></html>",
+        "noQuirksBodyHtml": "<style>...<!--[if IE]><style>...</style>X"
+      }
+    },
+    {
+      "data": "<!doctype html><title><!--<title></title>--></title>",
+      "errors": [
+        "(1,52): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<!--<title>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><title>&lt;!--&lt;title&gt;</title></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<title>&lt;!--&lt;title&gt;</title>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><title>&lt;/title></title>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "</title>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><title>&lt;/title&gt;</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>&lt;/title&gt;</title>"
+      }
+    },
+    {
+      "data": "<!doctype html><title>foo/title><link></head><body>X",
+      "errors": [
+        "(1,52): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "foo/title><link></head><body>X",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><title>foo/title&gt;&lt;link&gt;&lt;/head&gt;&lt;body&gt;X</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>foo/title&gt;&lt;link&gt;&lt;/head&gt;&lt;body&gt;X</title>"
+      }
+    },
+    {
+      "data": "<!doctype html><noscript><!--<noscript></noscript>--></noscript>",
+      "errors": [
+        "(1,64): unexpected-end-tag"
+      ],
+      "script": "on",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "<!--<noscript>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><noscript><!--<noscript></noscript></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--&lt;noscript&gt;</noscript>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><noscript><!--<noscript></noscript>--></noscript>",
+      "errors": [],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "<noscript></noscript>"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><noscript><!--<noscript></noscript>--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--&lt;noscript&gt;</noscript>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><noscript><!--</noscript>X<noscript>--></noscript>",
+      "errors": [],
+      "script": "on",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  },
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "-->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><noscript><!--</noscript></head><body>X<noscript>--></noscript></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>X<noscript>--&gt;</noscript>"
+      }
+    },
+    {
+      "data": "<!doctype html><noscript><!--</noscript>X<noscript>--></noscript>",
+      "errors": [],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "</noscript>X<noscript>"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><noscript><!--</noscript>X<noscript>--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>X<noscript>--&gt;</noscript>"
+      }
+    },
+    {
+      "data": "<!doctype html><noscript><iframe></noscript>X",
+      "errors": [],
+      "script": "on",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "<iframe>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><noscript><iframe></noscript></head><body>X</body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;iframe&gt;</noscript>X"
+      }
+    },
+    {
+      "data": "<!doctype html><noscript><iframe></noscript>X",
+      "errors": [
+        " * (1,34) unexpected token in head noscript",
+        " * (1,46) unexpected EOF"
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true,
+            "iframe": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript"
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe",
+                    "children": [
+                      {
+                        "text": "</noscript>X",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><noscript></noscript></head><body><iframe></noscript>X</iframe></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;iframe&gt;</noscript>X"
+      }
+    },
+    {
+      "data": "<!doctype html><noframes><!--<noframes></noframes>--></noframes>",
+      "errors": [
+        "(1,64): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noframes": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noframes",
+                    "children": [
+                      {
+                        "text": "<!--<noframes>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><noframes><!--<noframes></noframes></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<noframes><!--<noframes></noframes>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><noframes><body><script><!--...</script></body></noframes></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noframes": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noframes",
+                    "children": [
+                      {
+                        "text": "<body><script><!--...</script></body>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><noframes><body><script><!--...</script></body></noframes></head><body></body></html>",
+        "noQuirksBodyHtml": "<noframes><body><script><!--...</script></body></noframes>"
+      }
+    },
+    {
+      "data": "<!doctype html><textarea><!--<textarea></textarea>--></textarea>",
+      "errors": [
+        "(1,64): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "<!--<textarea>",
+                        "escaped": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><textarea>&lt;!--&lt;textarea&gt;</textarea>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<textarea>&lt;!--&lt;textarea&gt;</textarea>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><textarea>&lt;/textarea></textarea>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "</textarea>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><textarea>&lt;/textarea&gt;</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>&lt;/textarea&gt;</textarea>"
+      }
+    },
+    {
+      "data": "<!doctype html><textarea>&lt;</textarea>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "<",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><textarea>&lt;</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>&lt;</textarea>"
+      }
+    },
+    {
+      "data": "<!doctype html><textarea>a&lt;b</textarea>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "a<b",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><textarea>a&lt;b</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>a&lt;b</textarea>"
+      }
+    },
+    {
+      "data": "<!doctype html><iframe><!--<iframe></iframe>--></iframe>",
+      "errors": [
+        "(1,56): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "iframe": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe",
+                    "children": [
+                      {
+                        "text": "<!--<iframe>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><iframe><!--<iframe></iframe>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<iframe><!--<iframe></iframe>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><iframe>...<!--X->...<!--/X->...</iframe>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "iframe": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe",
+                    "children": [
+                      {
+                        "text": "...<!--X->...<!--/X->...",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><iframe>...<!--X->...<!--/X->...</iframe></body></html>",
+        "noQuirksBodyHtml": "<iframe>...<!--X->...<!--/X->...</iframe>"
+      }
+    },
+    {
+      "data": "<!doctype html><xmp><!--<xmp></xmp>--></xmp>",
+      "errors": [
+        "(1,44): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "xmp": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "xmp",
+                    "children": [
+                      {
+                        "text": "<!--<xmp>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><xmp><!--<xmp></xmp>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<xmp><!--<xmp></xmp>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><noembed><!--<noembed></noembed>--></noembed>",
+      "errors": [
+        "(1,60): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "noembed": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "noembed",
+                    "children": [
+                      {
+                        "text": "<!--<noembed>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><noembed><!--<noembed></noembed>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<noembed><!--<noembed></noembed>--&gt;"
+      }
+    },
+    {
+      "data": "<script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,8): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script>"
+      }
+    },
+    {
+      "data": "<script>a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,9): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script>a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script>a</script>"
+      }
+    },
+    {
+      "data": "<script><",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,9): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><</script>"
+      }
+    },
+    {
+      "data": "<script></",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,10): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></</script>"
+      }
+    },
+    {
+      "data": "<script></S",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,11): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</S",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></S</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></S</script>"
+      }
+    },
+    {
+      "data": "<script></SC",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,12): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SC",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></SC</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SC</script>"
+      }
+    },
+    {
+      "data": "<script></SCR",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,13): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SCR",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></SCR</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SCR</script>"
+      }
+    },
+    {
+      "data": "<script></SCRI",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,14): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SCRI",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></SCRI</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SCRI</script>"
+      }
+    },
+    {
+      "data": "<script></SCRIP",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,15): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SCRIP",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></SCRIP</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SCRIP</script>"
+      }
+    },
+    {
+      "data": "<script></SCRIPT",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,16): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</SCRIPT",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></SCRIPT</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></SCRIPT</script>"
+      }
+    },
+    {
+      "data": "<script></SCRIPT ",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,17): expected-attribute-name-but-got-eof",
+        "(1,17): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script>"
+      }
+    },
+    {
+      "data": "<script></s",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,11): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</s",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></s</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></s</script>"
+      }
+    },
+    {
+      "data": "<script></sc",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,12): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</sc",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></sc</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></sc</script>"
+      }
+    },
+    {
+      "data": "<script></scr",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,13): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</scr",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></scr</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></scr</script>"
+      }
+    },
+    {
+      "data": "<script></scri",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,14): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</scri",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></scri</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></scri</script>"
+      }
+    },
+    {
+      "data": "<script></scrip",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,15): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</scrip",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></scrip</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></scrip</script>"
+      }
+    },
+    {
+      "data": "<script></script",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,16): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script</script>"
+      }
+    },
+    {
+      "data": "<script></script ",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,17): expected-attribute-name-but-got-eof",
+        "(1,17): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script>"
+      }
+    },
+    {
+      "data": "<script><!",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,10): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!</script>"
+      }
+    },
+    {
+      "data": "<script><!a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,11): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!a</script>"
+      }
+    },
+    {
+      "data": "<script><!-",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,11): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!-",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!-</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!-</script>"
+      }
+    },
+    {
+      "data": "<script><!-a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,12): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!-a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!-a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!-a</script>"
+      }
+    },
+    {
+      "data": "<script><!--",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,12): expected-named-closing-tag-but-got-eof",
+        "(1,12): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--</script>"
+      }
+    },
+    {
+      "data": "<script><!--a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,13): expected-named-closing-tag-but-got-eof",
+        "(1,13): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--a</script>"
+      }
+    },
+    {
+      "data": "<script><!--<",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,13): expected-named-closing-tag-but-got-eof",
+        "(1,13): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<</script>"
+      }
+    },
+    {
+      "data": "<script><!--<a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,14): expected-named-closing-tag-but-got-eof",
+        "(1,14): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<a</script>"
+      }
+    },
+    {
+      "data": "<script><!--</",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,14): expected-named-closing-tag-but-got-eof",
+        "(1,14): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--</",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--</</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--</</script>"
+      }
+    },
+    {
+      "data": "<script><!--</script",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,20): expected-named-closing-tag-but-got-eof",
+        "(1,20): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--</script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--</script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--</script</script>"
+      }
+    },
+    {
+      "data": "<script><!--</script ",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,21): expected-attribute-name-but-got-eof",
+        "(1,21): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--</script>"
+      }
+    },
+    {
+      "data": "<script><!--<s",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,14): expected-named-closing-tag-but-got-eof",
+        "(1,14): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<s",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<s</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<s</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,19): expected-named-closing-tag-but-got-eof",
+        "(1,19): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script ",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,20): eof-in-script-in-script",
+        "(1,20): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script>"
+      }
+    },
+    {
+      "data": "<script><!--<script <",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,21): eof-in-script-in-script",
+        "(1,21): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script <",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script <</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script <</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script <a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,22): eof-in-script-in-script",
+        "(1,22): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script <a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script <a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script <a</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,22): eof-in-script-in-script",
+        "(1,22): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </s",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,23): eof-in-script-in-script",
+        "(1,23): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </s",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </s</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </s</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,28): eof-in-script-in-script",
+        "(1,28): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </scripta",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,29): eof-in-script-in-script",
+        "(1,29): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </scripta",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </scripta</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </scripta</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script ",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,29): expected-named-closing-tag-but-got-eof",
+        "(1,29): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,29): expected-named-closing-tag-but-got-eof",
+        "(1,29): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script/",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,29): expected-named-closing-tag-but-got-eof",
+        "(1,29): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script/",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script/</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script/</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script <",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,30): expected-named-closing-tag-but-got-eof",
+        "(1,30): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script <",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script <</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script <</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script <a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,31): expected-named-closing-tag-but-got-eof",
+        "(1,31): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script <a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script <a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script <a</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script </",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,31): expected-named-closing-tag-but-got-eof",
+        "(1,31): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script </",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script </</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script </script",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,37): expected-named-closing-tag-but-got-eof",
+        "(1,37): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script </script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script </script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script </script ",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,38): expected-attribute-name-but-got-eof",
+        "(1,38): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script </script/",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,38): unexpected-EOF-after-solidus-in-tag",
+        "(1,38): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script>"
+      }
+    },
+    {
+      "data": "<script><!--<script </script </script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script </script ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script </script </script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script </script </script>"
+      }
+    },
+    {
+      "data": "<script><!--<script -",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,21): eof-in-script-in-script",
+        "(1,21): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script -</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script -</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script -a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,22): eof-in-script-in-script",
+        "(1,22): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script -a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script -a</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script --",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,22): eof-in-script-in-script",
+        "(1,22): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script --a",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,23): eof-in-script-in-script",
+        "(1,23): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --a",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --a</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --a</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script -->",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,23): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script --><",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,24): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --><",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --><</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --><</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script --></",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,25): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --></",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --></</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script --></script",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,31): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script --></script",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --></script</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script --></script ",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,32): expected-attribute-name-but-got-eof",
+        "(1,32): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script --></script/",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,32): unexpected-EOF-after-solidus-in-tag",
+        "(1,32): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script --></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script -->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script --></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script --></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script><\\/script>--></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script><\\/script>-->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script><\\/script>--></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script><\\/script>--></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script></scr'+'ipt>--></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></scr'+'ipt>-->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script></scr'+'ipt>--></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></scr'+'ipt>--></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script></script><script></script></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script></script><script></script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script></script><script></script>--><!--</script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>--><!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script></script><script></script>--><!--</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>--><!--</script>"
+      }
+    },
+    {
+      "data": "<script><!--<script></script><script></script>-- ></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>-- >",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script></script><script></script>-- ></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>-- ></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script></script><script></script>- -></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>- ->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script></script><script></script>- -></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>- -></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script></script><script></script>- - ></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>- - >",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script></script><script></script>- - ></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>- - ></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script></script><script></script>-></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></script><script></script>->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script></script><script></script>-></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></script><script></script>-></script>"
+      }
+    },
+    {
+      "data": "<script><!--<script>--!></script>X",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,34): expected-named-closing-tag-but-got-eof",
+        "(1,34): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script>--!></script>X",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script>--!></script>X</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script>--!></script>X</script>"
+      }
+    },
+    {
+      "data": "<script><!--<scr'+'ipt></script>--></script>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,44): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<scr'+'ipt>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<scr'+'ipt></script></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<script><!--<scr'+'ipt></script>--&gt;"
+      }
+    },
+    {
+      "data": "<script><!--<script></scr'+'ipt></script>X",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,42): expected-named-closing-tag-but-got-eof",
+        "(1,42): unexpected-eof-in-text-mode"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "<!--<script></scr'+'ipt></script>X",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script><!--<script></scr'+'ipt></script>X</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script><!--<script></scr'+'ipt></script>X</script>"
+      }
+    },
+    {
+      "data": "<style><!--<style></style>--></style>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,37): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--<style>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--<style></style></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<style><!--<style></style>--&gt;"
+      }
+    },
+    {
+      "data": "<style><!--</style>X",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--</style></head><body>X</body></html>",
+        "noQuirksBodyHtml": "<style><!--</style>X"
+      }
+    },
+    {
+      "data": "<style><!--...</style>...--></style>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,36): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--...",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "...-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--...</style></head><body>...--&gt;</body></html>",
+        "noQuirksBodyHtml": "<style><!--...</style>...--&gt;"
+      }
+    },
+    {
+      "data": "<style><!--<br><html xmlns:v=\"urn:schemas-microsoft-com:vml\"><!--[if !mso]><style></style>X",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--<br><html xmlns:v=\"urn:schemas-microsoft-com:vml\"><!--[if !mso]><style>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--<br><html xmlns:v=\"urn:schemas-microsoft-com:vml\"><!--[if !mso]><style></style></head><body>X</body></html>",
+        "noQuirksBodyHtml": "<style><!--<br><html xmlns:v=\"urn:schemas-microsoft-com:vml\"><!--[if !mso]><style></style>X"
+      }
+    },
+    {
+      "data": "<style><!--...<style><!--...--!></style>--></style>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,51): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--...<style><!--...--!>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--...<style><!--...--!></style></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<style><!--...<style><!--...--!></style>--&gt;"
+      }
+    },
+    {
+      "data": "<style><!--...</style><!-- --><style>@import ...</style>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "<!--...",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "comment": " "
+                  },
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "@import ...",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style><!--...</style><!-- --><style>@import ...</style></head><body></body></html>",
+        "noQuirksBodyHtml": "<style><!--...</style><!-- --><style>@import ...</style>"
+      }
+    },
+    {
+      "data": "<style>...<style><!--...</style><!-- --></style>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,48): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "...<style><!--...",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "comment": " "
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style>...<style><!--...</style><!-- --></head><body></body></html>",
+        "noQuirksBodyHtml": "<style>...<style><!--...</style><!-- -->"
+      }
+    },
+    {
+      "data": "<style>...<!--[if IE]><style>...</style>X",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "...<!--[if IE]><style>...",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style>...<!--[if IE]><style>...</style></head><body>X</body></html>",
+        "noQuirksBodyHtml": "<style>...<!--[if IE]><style>...</style>X"
+      }
+    },
+    {
+      "data": "<title><!--<title></title>--></title>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,37): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<!--<title>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title>&lt;!--&lt;title&gt;</title></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<title>&lt;!--&lt;title&gt;</title>--&gt;"
+      }
+    },
+    {
+      "data": "<title>&lt;/title></title>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "</title>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title>&lt;/title&gt;</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>&lt;/title&gt;</title>"
+      }
+    },
+    {
+      "data": "<title>foo/title><link></head><body>X",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,37): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "foo/title><link></head><body>X",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title>foo/title&gt;&lt;link&gt;&lt;/head&gt;&lt;body&gt;X</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>foo/title&gt;&lt;link&gt;&lt;/head&gt;&lt;body&gt;X</title>"
+      }
+    },
+    {
+      "data": "<noscript><!--<noscript></noscript>--></noscript>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,49): unexpected-end-tag"
+      ],
+      "script": "on",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "<!--<noscript>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><!--<noscript></noscript></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--&lt;noscript&gt;</noscript>--&gt;"
+      }
+    },
+    {
+      "data": "<noscript><!--<noscript></noscript>--></noscript>",
+      "errors": [
+        " * (1,11) missing DOCTYPE"
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "<noscript></noscript>"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><!--<noscript></noscript>--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--&lt;noscript&gt;</noscript>--&gt;"
+      }
+    },
+    {
+      "data": "<noscript><!--</noscript>X<noscript>--></noscript>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "script": "on",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  },
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "-->",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><!--</noscript></head><body>X<noscript>--></noscript></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>X<noscript>--&gt;</noscript>"
+      }
+    },
+    {
+      "data": "<noscript><!--</noscript>X<noscript>--></noscript>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "</noscript>X<noscript>"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><!--</noscript>X<noscript>--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>X<noscript>--&gt;</noscript>"
+      }
+    },
+    {
+      "data": "<noscript><iframe></noscript>X",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "script": "on",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "<iframe>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><iframe></noscript></head><body>X</body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;iframe&gt;</noscript>X"
+      }
+    },
+    {
+      "data": "<noscript><iframe></noscript>X",
+      "errors": [
+        " * (1,11) missing DOCTYPE",
+        " * (1,19) unexpected token in head noscript",
+        " * (1,31) unexpected EOF"
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true,
+            "iframe": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript"
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe",
+                    "children": [
+                      {
+                        "text": "</noscript>X",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript></noscript></head><body><iframe></noscript>X</iframe></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;iframe&gt;</noscript>X"
+      }
+    },
+    {
+      "data": "<noframes><!--<noframes></noframes>--></noframes>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,49): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noframes": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noframes",
+                    "children": [
+                      {
+                        "text": "<!--<noframes>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noframes><!--<noframes></noframes></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<noframes><!--<noframes></noframes>--&gt;"
+      }
+    },
+    {
+      "data": "<noframes><body><script><!--...</script></body></noframes></html>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noframes": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noframes",
+                    "children": [
+                      {
+                        "text": "<body><script><!--...</script></body>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noframes><body><script><!--...</script></body></noframes></head><body></body></html>",
+        "noQuirksBodyHtml": "<noframes><body><script><!--...</script></body></noframes>"
+      }
+    },
+    {
+      "data": "<textarea><!--<textarea></textarea>--></textarea>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,49): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "<!--<textarea>",
+                        "escaped": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><textarea>&lt;!--&lt;textarea&gt;</textarea>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<textarea>&lt;!--&lt;textarea&gt;</textarea>--&gt;"
+      }
+    },
+    {
+      "data": "<textarea>&lt;/textarea></textarea>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "</textarea>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><textarea>&lt;/textarea&gt;</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>&lt;/textarea&gt;</textarea>"
+      }
+    },
+    {
+      "data": "<iframe><!--<iframe></iframe>--></iframe>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,41): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "iframe": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe",
+                    "children": [
+                      {
+                        "text": "<!--<iframe>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><iframe><!--<iframe></iframe>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<iframe><!--<iframe></iframe>--&gt;"
+      }
+    },
+    {
+      "data": "<iframe>...<!--X->...<!--/X->...</iframe>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "iframe": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe",
+                    "children": [
+                      {
+                        "text": "...<!--X->...<!--/X->...",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><iframe>...<!--X->...<!--/X->...</iframe></body></html>",
+        "noQuirksBodyHtml": "<iframe>...<!--X->...<!--/X->...</iframe>"
+      }
+    },
+    {
+      "data": "<xmp><!--<xmp></xmp>--></xmp>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,29): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "xmp": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "xmp",
+                    "children": [
+                      {
+                        "text": "<!--<xmp>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><xmp><!--<xmp></xmp>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<xmp><!--<xmp></xmp>--&gt;"
+      }
+    },
+    {
+      "data": "<noembed><!--<noembed></noembed>--></noembed>",
+      "errors": [
+        "(1,9): expected-doctype-but-got-start-tag",
+        "(1,45): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "noembed": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "noembed",
+                    "children": [
+                      {
+                        "text": "<!--<noembed>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><noembed><!--<noembed></noembed>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<noembed><!--<noembed></noembed>--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><table>\n",
+      "errors": [
+        "(2,0): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "text": "\n"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table>\n</table></body></html>",
+        "noQuirksBodyHtml": "<table>\n</table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><td><span><font></span><span>",
+      "errors": [
+        "(1,26): unexpected-cell-in-table-body",
+        "(1,45): unexpected-end-tag",
+        "(1,51): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "span": true,
+            "font": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "span",
+                                    "children": [
+                                      {
+                                        "tag": "font"
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "tag": "font",
+                                    "children": [
+                                      {
+                                        "tag": "span"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><span><font></font></span><font><span></span></font></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><span><font></font></span><font><span></span></font></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><form><table></form><form></table></form>",
+      "errors": [
+        "(1,35): unexpected-end-tag-implies-table-voodoo",
+        "(1,35): unexpected-end-tag",
+        "(1,41): unexpected-form-in-table",
+        "(1,56): unexpected-end-tag",
+        "(1,56): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "form"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><form><table><form></form></table></form></body></html>",
+        "noQuirksBodyHtml": "<form><table><form></form></table></form>"
+      }
+    }
+  ],
+  "tests17.dat": [
+    {
+      "data": "<!doctype html><table><tbody><select><tr>",
+      "errors": [
+        "(1,37): unexpected-start-tag-implies-table-voodoo",
+        "(1,41): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,41): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<select></select><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr><select><td>",
+      "errors": [
+        "(1,34): unexpected-start-tag-implies-table-voodoo",
+        "(1,38): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select><table><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<select></select><table><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr><td><select><td>",
+      "errors": [
+        "(1,42): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,42): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "select"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><select></select></td><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><select></select></td><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr><th><select><td>",
+      "errors": [
+        "(1,42): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,42): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "th": true,
+            "select": true,
+            "td": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "th",
+                                "children": [
+                                  {
+                                    "tag": "select"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><th><select></select></th><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><th><select></select></th><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><caption><select><tr>",
+      "errors": [
+        "(1,43): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,43): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "select": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "select"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><select></select></caption><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption><select></select></caption><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><tr>",
+      "errors": [
+        "(1,27): unexpected-start-tag-in-select",
+        "(1,27): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><td>",
+      "errors": [
+        "(1,27): unexpected-start-tag-in-select",
+        "(1,27): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><th>",
+      "errors": [
+        "(1,27): unexpected-start-tag-in-select",
+        "(1,27): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><tbody>",
+      "errors": [
+        "(1,30): unexpected-start-tag-in-select",
+        "(1,30): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><thead>",
+      "errors": [
+        "(1,30): unexpected-start-tag-in-select",
+        "(1,30): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><tfoot>",
+      "errors": [
+        "(1,30): unexpected-start-tag-in-select",
+        "(1,30): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><caption>",
+      "errors": [
+        "(1,32): unexpected-start-tag-in-select",
+        "(1,32): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr></table>a",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr></tr></tbody></table>a</body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr></tr></tbody></table>a"
+      }
+    }
+  ],
+  "tests18.dat": [
+    {
+      "data": "<!doctype html><plaintext></plaintext>",
+      "errors": [
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "plaintext": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "text": "</plaintext>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><plaintext></plaintext></plaintext></body></html>",
+        "noQuirksBodyHtml": "<plaintext></plaintext></plaintext>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><plaintext></plaintext>",
+      "errors": [
+        "(1,33): foster-parenting-start-tag",
+        "(1,34): foster-parenting-character",
+        "(1,35): foster-parenting-character",
+        "(1,36): foster-parenting-character",
+        "(1,37): foster-parenting-character",
+        "(1,38): foster-parenting-character",
+        "(1,39): foster-parenting-character",
+        "(1,40): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,42): foster-parenting-character",
+        "(1,43): foster-parenting-character",
+        "(1,44): foster-parenting-character",
+        "(1,45): foster-parenting-character",
+        "(1,45): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "plaintext": true,
+            "table": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "text": "</plaintext>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><plaintext></plaintext></plaintext><table></table></body></html>",
+        "noQuirksBodyHtml": "<plaintext></plaintext></plaintext><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tbody><plaintext></plaintext>",
+      "errors": [
+        "(1,40): foster-parenting-start-tag",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,52): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "plaintext": true,
+            "table": true,
+            "tbody": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "text": "</plaintext>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><plaintext></plaintext></plaintext><table><tbody></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<plaintext></plaintext></plaintext><table><tbody></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tbody><tr><plaintext></plaintext>",
+      "errors": [
+        "(1,44): foster-parenting-start-tag",
+        "(1,45): foster-parenting-character",
+        "(1,46): foster-parenting-character",
+        "(1,47): foster-parenting-character",
+        "(1,48): foster-parenting-character",
+        "(1,49): foster-parenting-character",
+        "(1,50): foster-parenting-character",
+        "(1,51): foster-parenting-character",
+        "(1,52): foster-parenting-character",
+        "(1,53): foster-parenting-character",
+        "(1,54): foster-parenting-character",
+        "(1,55): foster-parenting-character",
+        "(1,56): foster-parenting-character",
+        "(1,56): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "plaintext": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "text": "</plaintext>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><plaintext></plaintext></plaintext><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<plaintext></plaintext></plaintext><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><td><plaintext></plaintext>",
+      "errors": [
+        "(1,26): unexpected-cell-in-table-body",
+        "(1,49): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "plaintext": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "plaintext",
+                                    "children": [
+                                      {
+                                        "text": "</plaintext>",
+                                        "no_escape": true
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><plaintext></plaintext></plaintext></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><plaintext></plaintext></plaintext></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><caption><plaintext></plaintext>",
+      "errors": [
+        "(1,54): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "plaintext": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "plaintext",
+                            "children": [
+                              {
+                                "text": "</plaintext>",
+                                "no_escape": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><plaintext></plaintext></plaintext></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption><plaintext></plaintext></plaintext></caption></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr><style></script></style>abc",
+      "errors": [
+        "(1,51): foster-parenting-character",
+        "(1,52): foster-parenting-character",
+        "(1,53): foster-parenting-character",
+        "(1,53): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "style": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "abc"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "style",
+                                "children": [
+                                  {
+                                    "text": "</script>",
+                                    "no_escape": true
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>abc<table><tbody><tr><style></script></style></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "abc<table><tbody><tr><style></script></style></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr><script></style></script>abc",
+      "errors": [
+        "(1,52): foster-parenting-character",
+        "(1,53): foster-parenting-character",
+        "(1,54): foster-parenting-character",
+        "(1,54): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "script": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "abc"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "script",
+                                "children": [
+                                  {
+                                    "text": "</style>",
+                                    "no_escape": true
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>abc<table><tbody><tr><script></style></script></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "abc<table><tbody><tr><script></style></script></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><caption><style></script></style>abc",
+      "errors": [
+        "(1,58): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "style": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "style",
+                            "children": [
+                              {
+                                "text": "</script>",
+                                "no_escape": true
+                              }
+                            ]
+                          },
+                          {
+                            "text": "abc"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><style></script></style>abc</caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption><style></script></style>abc</caption></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><td><style></script></style>abc",
+      "errors": [
+        "(1,26): unexpected-cell-in-table-body",
+        "(1,53): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "style": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "style",
+                                    "children": [
+                                      {
+                                        "text": "</script>",
+                                        "no_escape": true
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "text": "abc"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><style></script></style>abc</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><style></script></style>abc</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><script></style></script>abc",
+      "errors": [
+        "(1,51): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "script": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "script",
+                        "children": [
+                          {
+                            "text": "</style>",
+                            "no_escape": true
+                          }
+                        ]
+                      },
+                      {
+                        "text": "abc"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><script></style></script>abc</select></body></html>",
+        "noQuirksBodyHtml": "<select><script></style></script>abc</select>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><select><script></style></script>abc",
+      "errors": [
+        "(1,30): unexpected-start-tag-implies-table-voodoo",
+        "(1,58): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "script": true,
+            "table": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "script",
+                        "children": [
+                          {
+                            "text": "</style>",
+                            "no_escape": true
+                          }
+                        ]
+                      },
+                      {
+                        "text": "abc"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><script></style></script>abc</select><table></table></body></html>",
+        "noQuirksBodyHtml": "<select><script></style></script>abc</select><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr><select><script></style></script>abc",
+      "errors": [
+        "(1,34): unexpected-start-tag-implies-table-voodoo",
+        "(1,62): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "script": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "script",
+                        "children": [
+                          {
+                            "text": "</style>",
+                            "no_escape": true
+                          }
+                        ]
+                      },
+                      {
+                        "text": "abc"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><script></style></script>abc</select><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<select><script></style></script>abc</select><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><frameset></frameset><noframes>abc",
+      "errors": [
+        "(1,49): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "noframes": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "tag": "noframes",
+                "children": [
+                  {
+                    "text": "abc",
+                    "no_escape": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset><noframes>abc</noframes></html>",
+        "noQuirksBodyHtml": "<noframes>abc</noframes>"
+      }
+    },
+    {
+      "data": "<!doctype html><frameset></frameset><noframes>abc</noframes><!--abc-->",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "noframes": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "tag": "noframes",
+                "children": [
+                  {
+                    "text": "abc",
+                    "no_escape": true
+                  }
+                ]
+              },
+              {
+                "comment": "abc"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset><noframes>abc</noframes><!--abc--></html>",
+        "noQuirksBodyHtml": "<noframes>abc</noframes><!--abc-->"
+      }
+    },
+    {
+      "data": "<!doctype html><frameset></frameset></html><noframes>abc",
+      "errors": [
+        "(1,56): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "noframes": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "tag": "noframes",
+                "children": [
+                  {
+                    "text": "abc",
+                    "no_escape": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset><noframes>abc</noframes></html>",
+        "noQuirksBodyHtml": "<noframes>abc</noframes>"
+      }
+    },
+    {
+      "data": "<!doctype html><frameset></frameset></html><noframes>abc</noframes><!--abc-->",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "noframes": true
+          },
+          "doctype": true,
+          "no_escape": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "tag": "noframes",
+                "children": [
+                  {
+                    "text": "abc",
+                    "no_escape": true
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "comment": "abc"
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset><noframes>abc</noframes></html><!--abc-->",
+        "noQuirksBodyHtml": "<noframes>abc</noframes><!--abc-->"
+      }
+    },
+    {
+      "data": "<!doctype html><table><tr></tbody><tfoot>",
+      "errors": [
+        "(1,41): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "tfoot": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "tfoot"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr></tr></tbody><tfoot></tfoot></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr></tr></tbody><tfoot></tfoot></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><td><svg></svg>abc<td>",
+      "errors": [
+        "(1,26): unexpected-cell-in-table-body",
+        "(1,44): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg"
+                                  },
+                                  {
+                                    "text": "abc"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><svg></svg>abc</td><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><svg></svg>abc</td><td></td></tr></tbody></table>"
+      }
+    }
+  ],
+  "tests19.dat": [
+    {
+      "data": "<!doctype html><math><mn DefinitionUrl=\"foo\">",
+      "errors": [
+        "(1,45): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mn": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mn",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "definitionURL",
+                            "value": "foo"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mn definitionURL=\"foo\"></mn></math></body></html>",
+        "noQuirksBodyHtml": "<math><mn definitionURL=\"foo\"></mn></math>"
+      }
+    },
+    {
+      "data": "<!doctype html><html></p><!--foo-->",
+      "errors": [
+        "(1,25): end-tag-after-implied-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "comment": "foo"
+              },
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><!--foo--><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<p></p><!--foo-->"
+      }
+    },
+    {
+      "data": "<!doctype html><head></head></p><!--foo-->",
+      "errors": [
+        "(1,32): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "comment": "foo"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><!--foo--><body></body></html>",
+        "noQuirksBodyHtml": "<p></p><!--foo-->"
+      }
+    },
+    {
+      "data": "<!doctype html><body><p><pre>",
+      "errors": [
+        "(1,29): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "pre": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "pre"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><pre></pre></body></html>",
+        "noQuirksBodyHtml": "<p></p><pre></pre>"
+      }
+    },
+    {
+      "data": "<!doctype html><body><p><listing>",
+      "errors": [
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "listing": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "listing"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><listing></listing></body></html>",
+        "noQuirksBodyHtml": "<p></p><listing></listing>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><plaintext>",
+      "errors": [
+        "(1,29): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "plaintext": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "plaintext"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><plaintext></plaintext></body></html>",
+        "noQuirksBodyHtml": "<p></p><plaintext></plaintext>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><h1>",
+      "errors": [
+        "(1,22): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "h1": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "h1"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><h1></h1></body></html>",
+        "noQuirksBodyHtml": "<p></p><h1></h1>"
+      }
+    },
+    {
+      "data": "<!doctype html><form><isindex>",
+      "errors": [
+        "(1,30): deprecated-tag",
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><form></form></body></html>",
+        "noQuirksBodyHtml": "<form></form>"
+      }
+    },
+    {
+      "data": "<!doctype html><isindex action=\"POST\">",
+      "errors": [
+        "(1,38): deprecated-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "hr": true,
+            "label": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "attrs": [
+                      {
+                        "name": "action",
+                        "value": "POST"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "hr"
+                      },
+                      {
+                        "tag": "label",
+                        "children": [
+                          {
+                            "text": "This is a searchable index. Enter search keywords: "
+                          },
+                          {
+                            "tag": "input",
+                            "attrs": [
+                              {
+                                "name": "name",
+                                "value": "isindex"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "hr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><form action=\"POST\"><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form></body></html>",
+        "noQuirksBodyHtml": "<form action=\"POST\"><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>"
+      }
+    },
+    {
+      "data": "<!doctype html><isindex prompt=\"this is isindex\">",
+      "errors": [
+        "(1,49): deprecated-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "hr": true,
+            "label": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "hr"
+                      },
+                      {
+                        "tag": "label",
+                        "children": [
+                          {
+                            "text": "this is isindex"
+                          },
+                          {
+                            "tag": "input",
+                            "attrs": [
+                              {
+                                "name": "name",
+                                "value": "isindex"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "hr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><form><hr><label>this is isindex<input name=\"isindex\"></label><hr></form></body></html>",
+        "noQuirksBodyHtml": "<form><hr><label>this is isindex<input name=\"isindex\"></label><hr></form>"
+      }
+    },
+    {
+      "data": "<!doctype html><isindex type=\"hidden\">",
+      "errors": [
+        "(1,38): deprecated-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "hr": true,
+            "label": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "hr"
+                      },
+                      {
+                        "tag": "label",
+                        "children": [
+                          {
+                            "text": "This is a searchable index. Enter search keywords: "
+                          },
+                          {
+                            "tag": "input",
+                            "attrs": [
+                              {
+                                "name": "name",
+                                "value": "isindex"
+                              },
+                              {
+                                "name": "type",
+                                "value": "hidden"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "hr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\" type=\"hidden\"></label><hr></form></body></html>",
+        "noQuirksBodyHtml": "<form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\" type=\"hidden\"></label><hr></form>"
+      }
+    },
+    {
+      "data": "<!doctype html><isindex name=\"foo\">",
+      "errors": [
+        "(1,35): deprecated-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "hr": true,
+            "label": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "hr"
+                      },
+                      {
+                        "tag": "label",
+                        "children": [
+                          {
+                            "text": "This is a searchable index. Enter search keywords: "
+                          },
+                          {
+                            "tag": "input",
+                            "attrs": [
+                              {
+                                "name": "name",
+                                "value": "isindex"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "hr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form></body></html>",
+        "noQuirksBodyHtml": "<form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>"
+      }
+    },
+    {
+      "data": "<!doctype html><ruby><p><rp>",
+      "errors": [
+        "(1,28): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "p": true,
+            "rp": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "p"
+                      },
+                      {
+                        "tag": "rp"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><ruby><p></p><rp></rp></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><p></p><rp></rp></ruby>"
+      }
+    },
+    {
+      "data": "<!doctype html><ruby><div><span><rp>",
+      "errors": [
+        "(1,36): XXX-undefined-error",
+        "(1,36): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "div": true,
+            "span": true,
+            "rp": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "span",
+                            "children": [
+                              {
+                                "tag": "rp"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><ruby><div><span><rp></rp></span></div></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><div><span><rp></rp></span></div></ruby>"
+      }
+    },
+    {
+      "data": "<!doctype html><ruby><div><p><rp>",
+      "errors": [
+        "(1,33): XXX-undefined-error",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "div": true,
+            "p": true,
+            "rp": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "p"
+                          },
+                          {
+                            "tag": "rp"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><ruby><div><p></p><rp></rp></div></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><div><p></p><rp></rp></div></ruby>"
+      }
+    },
+    {
+      "data": "<!doctype html><ruby><p><rt>",
+      "errors": [
+        "(1,28): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "p": true,
+            "rt": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "p"
+                      },
+                      {
+                        "tag": "rt"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><ruby><p></p><rt></rt></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><p></p><rt></rt></ruby>"
+      }
+    },
+    {
+      "data": "<!doctype html><ruby><div><span><rt>",
+      "errors": [
+        "(1,36): XXX-undefined-error",
+        "(1,36): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "div": true,
+            "span": true,
+            "rt": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "span",
+                            "children": [
+                              {
+                                "tag": "rt"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><ruby><div><span><rt></rt></span></div></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><div><span><rt></rt></span></div></ruby>"
+      }
+    },
+    {
+      "data": "<!doctype html><ruby><div><p><rt>",
+      "errors": [
+        "(1,33): XXX-undefined-error",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "div": true,
+            "p": true,
+            "rt": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "p"
+                          },
+                          {
+                            "tag": "rt"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><ruby><div><p></p><rt></rt></div></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><div><p></p><rt></rt></div></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rb>b<rt></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rb": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rb",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rt"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rb>b</rb><rt></rt></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rb>b</rb><rt></rt></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rp>b<rt></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rp": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rp",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rt"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rp>b</rp><rt></rt></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rp>b</rp><rt></rt></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rt>b<rt></ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rt",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rt"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rt>b</rt><rt></rt></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rt>b</rt><rt></rt></ruby>"
+      }
+    },
+    {
+      "data": "<html><ruby>a<rtc>b<rt>c<rb>d</ruby></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "rtc": true,
+            "rt": true,
+            "rb": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "rtc",
+                        "children": [
+                          {
+                            "text": "b"
+                          },
+                          {
+                            "tag": "rt",
+                            "children": [
+                              {
+                                "text": "c"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "rb",
+                        "children": [
+                          {
+                            "text": "d"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby>a<rtc>b<rt>c</rt></rtc><rb>d</rb></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby>a<rtc>b<rt>c</rt></rtc><rb>d</rb></ruby>"
+      }
+    },
+    {
+      "data": "<!doctype html><math/><foo>",
+      "errors": [
+        "(1,27): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "foo": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  },
+                  {
+                    "tag": "foo"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math></math><foo></foo></body></html>",
+        "noQuirksBodyHtml": "<math></math><foo></foo>"
+      }
+    },
+    {
+      "data": "<!doctype html><svg/><foo>",
+      "errors": [
+        "(1,26): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "foo": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  },
+                  {
+                    "tag": "foo"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg></svg><foo></foo></body></html>",
+        "noQuirksBodyHtml": "<svg></svg><foo></foo>"
+      }
+    },
+    {
+      "data": "<!doctype html><div></body><!--foo-->",
+      "errors": [
+        "(1,27): expected-one-end-tag-but-got-another"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  }
+                ]
+              },
+              {
+                "comment": "foo"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><div></div></body><!--foo--></html>",
+        "noQuirksBodyHtml": "<div><!--foo--></div>"
+      }
+    },
+    {
+      "data": "<!doctype html><h1><div><h3><span></h1>foo",
+      "errors": [
+        "(1,39): end-tag-too-early",
+        "(1,42): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "h1": true,
+            "div": true,
+            "h3": true,
+            "span": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "h1",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "h3",
+                            "children": [
+                              {
+                                "tag": "span"
+                              }
+                            ]
+                          },
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><h1><div><h3><span></span></h3>foo</div></h1></body></html>",
+        "noQuirksBodyHtml": "<h1><div><h3><span></span></h3>foo</div></h1>"
+      }
+    },
+    {
+      "data": "<!doctype html><p></h3>foo",
+      "errors": [
+        "(1,23): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p>foo</p></body></html>",
+        "noQuirksBodyHtml": "<p>foo</p>"
+      }
+    },
+    {
+      "data": "<!doctype html><h3><li>abc</h2>foo",
+      "errors": [
+        "(1,31): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "h3": true,
+            "li": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "h3",
+                    "children": [
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "text": "abc"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "foo"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><h3><li>abc</li></h3>foo</body></html>",
+        "noQuirksBodyHtml": "<h3><li>abc</li></h3>foo"
+      }
+    },
+    {
+      "data": "<!doctype html><table>abc<!--foo-->",
+      "errors": [
+        "(1,23): foster-parenting-character",
+        "(1,24): foster-parenting-character",
+        "(1,25): foster-parenting-character",
+        "(1,35): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "abc"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>abc<table><!--foo--></table></body></html>",
+        "noQuirksBodyHtml": "abc<table><!--foo--></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table>  <!--foo-->",
+      "errors": [
+        "(1,34): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "text": "  "
+                      },
+                      {
+                        "comment": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table>  <!--foo--></table></body></html>",
+        "noQuirksBodyHtml": "<table>  <!--foo--></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table> b <!--foo-->",
+      "errors": [
+        "(1,23): foster-parenting-character",
+        "(1,24): foster-parenting-character",
+        "(1,25): foster-parenting-character",
+        "(1,35): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": " b "
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body> b <table><!--foo--></table></body></html>",
+        "noQuirksBodyHtml": " b <table><!--foo--></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><option><option>",
+      "errors": [
+        "(1,39): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      },
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><option></option><option></option></select></body></html>",
+        "noQuirksBodyHtml": "<select><option></option><option></option></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><option></optgroup>",
+      "errors": [
+        "(1,42): unexpected-end-tag-in-select",
+        "(1,42): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><option></option></select></body></html>",
+        "noQuirksBodyHtml": "<select><option></option></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><option></optgroup>",
+      "errors": [
+        "(1,42): unexpected-end-tag-in-select",
+        "(1,42): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><option></option></select></body></html>",
+        "noQuirksBodyHtml": "<select><option></option></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><dd><optgroup><dd>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dd": true,
+            "optgroup": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dd",
+                    "children": [
+                      {
+                        "tag": "optgroup"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "dd"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><dd><optgroup></optgroup></dd><dd></dd></body></html>",
+        "noQuirksBodyHtml": "<dd><optgroup></optgroup></dd><dd></dd>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><math><mi><p><h1>",
+      "errors": [
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "math math": true,
+            "math mi": true,
+            "h1": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "math",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mi",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "p"
+                              },
+                              {
+                                "tag": "h1"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><math><mi><p></p><h1></h1></mi></math></p></body></html>",
+        "noQuirksBodyHtml": "<p><math><mi><p></p><h1></h1></mi></math></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><math><mo><p><h1>",
+      "errors": [
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "math math": true,
+            "math mo": true,
+            "h1": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "math",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mo",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "p"
+                              },
+                              {
+                                "tag": "h1"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><math><mo><p></p><h1></h1></mo></math></p></body></html>",
+        "noQuirksBodyHtml": "<p><math><mo><p></p><h1></h1></mo></math></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><math><mn><p><h1>",
+      "errors": [
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "math math": true,
+            "math mn": true,
+            "h1": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "math",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mn",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "p"
+                              },
+                              {
+                                "tag": "h1"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><math><mn><p></p><h1></h1></mn></math></p></body></html>",
+        "noQuirksBodyHtml": "<p><math><mn><p></p><h1></h1></mn></math></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><math><ms><p><h1>",
+      "errors": [
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "math math": true,
+            "math ms": true,
+            "h1": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "math",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "ms",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "p"
+                              },
+                              {
+                                "tag": "h1"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><math><ms><p></p><h1></h1></ms></math></p></body></html>",
+        "noQuirksBodyHtml": "<p><math><ms><p></p><h1></h1></ms></math></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><math><mtext><p><h1>",
+      "errors": [
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "math math": true,
+            "math mtext": true,
+            "h1": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "math",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mtext",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "p"
+                              },
+                              {
+                                "tag": "h1"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><math><mtext><p></p><h1></h1></mtext></math></p></body></html>",
+        "noQuirksBodyHtml": "<p><math><mtext><p></p><h1></h1></mtext></math></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><frameset></noframes>",
+      "errors": [
+        "(1,36): unexpected-end-tag-in-frameset",
+        "(1,36): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!doctype html><html c=d><body></html><html a=b>",
+      "errors": [
+        "(1,48): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "a",
+                "value": "b"
+              },
+              {
+                "name": "c",
+                "value": "d"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html c=\"d\" a=\"b\"><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!doctype html><html c=d><frameset></frameset></html><html a=b>",
+      "errors": [
+        "(1,63): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "a",
+                "value": "b"
+              },
+              {
+                "name": "c",
+                "value": "d"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html c=\"d\" a=\"b\"><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!doctype html><html><frameset></frameset></html><!--foo-->",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          },
+          {
+            "comment": "foo"
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html><!--foo-->",
+        "noQuirksBodyHtml": "<!--foo-->"
+      }
+    },
+    {
+      "data": "<!doctype html><html><frameset></frameset></html>  ",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "text": "  "
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset>  </html>",
+        "noQuirksBodyHtml": "  "
+      }
+    },
+    {
+      "data": "<!doctype html><html><frameset></frameset></html>abc",
+      "errors": [
+        "(1,50): expected-eof-but-got-char",
+        "(1,51): expected-eof-but-got-char",
+        "(1,52): expected-eof-but-got-char"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "abc"
+      }
+    },
+    {
+      "data": "<!doctype html><html><frameset></frameset></html><p>",
+      "errors": [
+        "(1,52): expected-eof-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<p></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><html><frameset></frameset></html></p>",
+      "errors": [
+        "(1,53): expected-eof-but-got-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<p></p>"
+      }
+    },
+    {
+      "data": "<html><frameset></frameset></html><!doctype html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,49): unexpected-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!doctype html><body><frameset>",
+      "errors": [
+        "(1,31): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!doctype html><p><frameset><frame>",
+      "errors": [
+        "(1,28): unexpected-start-tag",
+        "(1,35): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset><frame></frameset></html>",
+        "noQuirksBodyHtml": "<p></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p>a<frameset>",
+      "errors": [
+        "(1,29): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "a"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p>a</p></body></html>",
+        "noQuirksBodyHtml": "<p>a</p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p> <frameset><frame>",
+      "errors": [
+        "(1,29): unexpected-start-tag",
+        "(1,36): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset><frame></frameset></html>",
+        "noQuirksBodyHtml": "<p> </p>"
+      }
+    },
+    {
+      "data": "<!doctype html><pre><frameset>",
+      "errors": [
+        "(1,30): unexpected-start-tag",
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre></pre></body></html>",
+        "noQuirksBodyHtml": "<pre></pre>"
+      }
+    },
+    {
+      "data": "<!doctype html><listing><frameset>",
+      "errors": [
+        "(1,34): unexpected-start-tag",
+        "(1,34): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "listing": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "listing"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><listing></listing></body></html>",
+        "noQuirksBodyHtml": "<listing></listing>"
+      }
+    },
+    {
+      "data": "<!doctype html><li><frameset>",
+      "errors": [
+        "(1,29): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "li": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "li"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><li></li></body></html>",
+        "noQuirksBodyHtml": "<li></li>"
+      }
+    },
+    {
+      "data": "<!doctype html><dd><frameset>",
+      "errors": [
+        "(1,29): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dd": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dd"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><dd></dd></body></html>",
+        "noQuirksBodyHtml": "<dd></dd>"
+      }
+    },
+    {
+      "data": "<!doctype html><dt><frameset>",
+      "errors": [
+        "(1,29): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dt": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dt"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><dt></dt></body></html>",
+        "noQuirksBodyHtml": "<dt></dt>"
+      }
+    },
+    {
+      "data": "<!doctype html><button><frameset>",
+      "errors": [
+        "(1,33): unexpected-start-tag",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "button": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "button"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><button></button></body></html>",
+        "noQuirksBodyHtml": "<button></button>"
+      }
+    },
+    {
+      "data": "<!doctype html><applet><frameset>",
+      "errors": [
+        "(1,33): unexpected-start-tag",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "applet": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "applet"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><applet></applet></body></html>",
+        "noQuirksBodyHtml": "<applet></applet>"
+      }
+    },
+    {
+      "data": "<!doctype html><marquee><frameset>",
+      "errors": [
+        "(1,34): unexpected-start-tag",
+        "(1,34): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "marquee": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "marquee"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><marquee></marquee></body></html>",
+        "noQuirksBodyHtml": "<marquee></marquee>"
+      }
+    },
+    {
+      "data": "<!doctype html><object><frameset>",
+      "errors": [
+        "(1,33): unexpected-start-tag",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "object": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "object"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><object></object></body></html>",
+        "noQuirksBodyHtml": "<object></object>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><frameset>",
+      "errors": [
+        "(1,32): unexpected-start-tag-implies-table-voodoo",
+        "(1,32): unexpected-start-tag",
+        "(1,32): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table></table></body></html>",
+        "noQuirksBodyHtml": "<table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><area><frameset>",
+      "errors": [
+        "(1,31): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "area": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "area"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><area></body></html>",
+        "noQuirksBodyHtml": "<area>"
+      }
+    },
+    {
+      "data": "<!doctype html><basefont><frameset>",
+      "errors": [
+        "(1,35): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "basefont": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "basefont"
+                  }
+                ]
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><basefont></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<basefont>"
+      }
+    },
+    {
+      "data": "<!doctype html><bgsound><frameset>",
+      "errors": [
+        "(1,34): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "bgsound": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "bgsound"
+                  }
+                ]
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><bgsound></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<bgsound>"
+      }
+    },
+    {
+      "data": "<!doctype html><br><frameset>",
+      "errors": [
+        "(1,29): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "br": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "br"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><br></body></html>",
+        "noQuirksBodyHtml": "<br>"
+      }
+    },
+    {
+      "data": "<!doctype html><embed><frameset>",
+      "errors": [
+        "(1,32): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "embed": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "embed"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><embed></body></html>",
+        "noQuirksBodyHtml": "<embed>"
+      }
+    },
+    {
+      "data": "<!doctype html><img><frameset>",
+      "errors": [
+        "(1,30): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "img": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "img"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><img></body></html>",
+        "noQuirksBodyHtml": "<img>"
+      }
+    },
+    {
+      "data": "<!doctype html><input><frameset>",
+      "errors": [
+        "(1,32): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "input"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><input></body></html>",
+        "noQuirksBodyHtml": "<input>"
+      }
+    },
+    {
+      "data": "<!doctype html><keygen><frameset>",
+      "errors": [
+        "(1,33): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "keygen": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "keygen"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><keygen></body></html>",
+        "noQuirksBodyHtml": "<keygen>"
+      }
+    },
+    {
+      "data": "<!doctype html><wbr><frameset>",
+      "errors": [
+        "(1,30): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "wbr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "wbr"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><wbr></body></html>",
+        "noQuirksBodyHtml": "<wbr>"
+      }
+    },
+    {
+      "data": "<!doctype html><hr><frameset>",
+      "errors": [
+        "(1,29): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "hr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "hr"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><hr></body></html>",
+        "noQuirksBodyHtml": "<hr>"
+      }
+    },
+    {
+      "data": "<!doctype html><textarea></textarea><frameset>",
+      "errors": [
+        "(1,46): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><textarea></textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea></textarea>"
+      }
+    },
+    {
+      "data": "<!doctype html><xmp></xmp><frameset>",
+      "errors": [
+        "(1,36): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "xmp": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "xmp"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><xmp></xmp></body></html>",
+        "noQuirksBodyHtml": "<xmp></xmp>"
+      }
+    },
+    {
+      "data": "<!doctype html><iframe></iframe><frameset>",
+      "errors": [
+        "(1,42): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "iframe": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><iframe></iframe></body></html>",
+        "noQuirksBodyHtml": "<iframe></iframe>"
+      }
+    },
+    {
+      "data": "<!doctype html><select></select><frameset>",
+      "errors": [
+        "(1,42): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!doctype html><svg></svg><frameset><frame>",
+      "errors": [
+        "(1,36): unexpected-start-tag",
+        "(1,43): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset><frame></frameset></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<!doctype html><math></math><frameset><frame>",
+      "errors": [
+        "(1,38): unexpected-start-tag",
+        "(1,45): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset><frame></frameset></html>",
+        "noQuirksBodyHtml": "<math></math>"
+      }
+    },
+    {
+      "data": "<!doctype html><svg><foreignObject><div> <frameset><frame>",
+      "errors": [
+        "(1,51): unexpected-start-tag",
+        "(1,58): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset><frame></frameset></html>",
+        "noQuirksBodyHtml": "<svg><foreignObject><div> </div></foreignObject></svg>"
+      }
+    },
+    {
+      "data": "<!doctype html><svg>a</svg><frameset><frame>",
+      "errors": [
+        "(1,37): unexpected-start-tag",
+        "(1,44): unexpected-start-tag-ignored"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "a"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg>a</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>a</svg>"
+      }
+    },
+    {
+      "data": "<!doctype html><svg> </svg><frameset><frame>",
+      "errors": [
+        "(1,37): unexpected-start-tag",
+        "(1,44): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "frame": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "tag": "frame"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset><frame></frameset></html>",
+        "noQuirksBodyHtml": "<svg> </svg>"
+      }
+    },
+    {
+      "data": "<html>aaa<frameset></frameset>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,19): unexpected-start-tag",
+        "(1,30): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "aaa"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>aaa</body></html>",
+        "noQuirksBodyHtml": "aaa"
+      }
+    },
+    {
+      "data": "<html> a <frameset></frameset>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,19): unexpected-start-tag",
+        "(1,30): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "a "
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>a </body></html>",
+        "noQuirksBodyHtml": " a "
+      }
+    },
+    {
+      "data": "<!doctype html><div><frameset>",
+      "errors": [
+        "(1,30): unexpected-start-tag",
+        "(1,30): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<!doctype html><div><body><frameset>",
+      "errors": [
+        "(1,26): unexpected-start-tag",
+        "(1,36): unexpected-start-tag",
+        "(1,36): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><div></div></body></html>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><math></p>a",
+      "errors": [
+        "(1,28): unexpected-end-tag",
+        "(1,28): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "math math": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "math",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><math></math></p>a</body></html>",
+        "noQuirksBodyHtml": "<p><math></math></p>a"
+      }
+    },
+    {
+      "data": "<!doctype html><p><math><mn><span></p>a",
+      "errors": [
+        "(1,38): unexpected-end-tag",
+        "(1,39): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "math math": true,
+            "math mn": true,
+            "span": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "math",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mn",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "span",
+                                "children": [
+                                  {
+                                    "tag": "p"
+                                  },
+                                  {
+                                    "text": "a"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><math><mn><span><p></p>a</span></mn></math></p></body></html>",
+        "noQuirksBodyHtml": "<p><math><mn><span><p></p>a</span></mn></math></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><math></html>",
+      "errors": [
+        "(1,28): unexpected-end-tag",
+        "(1,28): expected-one-end-tag-but-got-another",
+        "(1,28): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math></math></body></html>",
+        "noQuirksBodyHtml": "<math></math>"
+      }
+    },
+    {
+      "data": "<!doctype html><meta charset=\"ascii\">",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "meta": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "meta",
+                    "attrs": [
+                      {
+                        "name": "charset",
+                        "value": "ascii"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><meta charset=\"ascii\"></head><body></body></html>",
+        "noQuirksBodyHtml": "<meta charset=\"ascii\">"
+      }
+    },
+    {
+      "data": "<!doctype html><meta http-equiv=\"content-type\" content=\"text/html;charset=ascii\">",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "meta": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "meta",
+                    "attrs": [
+                      {
+                        "name": "content",
+                        "value": "text/html;charset=ascii"
+                      },
+                      {
+                        "name": "http-equiv",
+                        "value": "content-type"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><meta http-equiv=\"content-type\" content=\"text/html;charset=ascii\"></head><body></body></html>",
+        "noQuirksBodyHtml": "<meta http-equiv=\"content-type\" content=\"text/html;charset=ascii\">"
+      }
+    },
+    {
+      "data": "<!doctype html><head><!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset=\"utf8\">",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "meta": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "comment": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                  },
+                  {
+                    "tag": "meta",
+                    "attrs": [
+                      {
+                        "name": "charset",
+                        "value": "utf8"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset=\"utf8\"></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset=\"utf8\">"
+      }
+    },
+    {
+      "data": "<!doctype html><html a=b><head></head><html c=d>",
+      "errors": [
+        "(1,48): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "a",
+                "value": "b"
+              },
+              {
+                "name": "c",
+                "value": "d"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html a=\"b\" c=\"d\"><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!doctype html><image/>",
+      "errors": [
+        "(1,23): image-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "img": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "img"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><img></body></html>",
+        "noQuirksBodyHtml": "<img>"
+      }
+    },
+    {
+      "data": "<!doctype html>a<i>b<table>c<b>d</i>e</b>f",
+      "errors": [
+        "(1,28): foster-parenting-character",
+        "(1,31): foster-parenting-start-tag",
+        "(1,32): foster-parenting-character",
+        "(1,36): foster-parenting-end-tag",
+        "(1,36): adoption-agency-1.3",
+        "(1,37): foster-parenting-character",
+        "(1,41): foster-parenting-end-tag",
+        "(1,42): foster-parenting-character",
+        "(1,42): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "i": true,
+            "b": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "a"
+                  },
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": "bc"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "de"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "f"
+                      },
+                      {
+                        "tag": "table"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>a<i>bc<b>de</b>f<table></table></i></body></html>",
+        "noQuirksBodyHtml": "a<i>bc<b>de</b>f<table></table></i>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f",
+      "errors": [
+        "(1,25): foster-parenting-start-tag",
+        "(1,26): foster-parenting-character",
+        "(1,29): foster-parenting-start-tag",
+        "(1,30): foster-parenting-character",
+        "(1,35): foster-parenting-start-tag",
+        "(1,36): foster-parenting-character",
+        "(1,39): foster-parenting-start-tag",
+        "(1,40): foster-parenting-character",
+        "(1,44): foster-parenting-end-tag",
+        "(1,44): adoption-agency-1.3",
+        "(1,44): adoption-agency-1.3",
+        "(1,45): foster-parenting-character",
+        "(1,49): foster-parenting-end-tag",
+        "(1,49): adoption-agency-1.3",
+        "(1,49): adoption-agency-1.3",
+        "(1,50): foster-parenting-character",
+        "(1,50): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "i": true,
+            "b": true,
+            "div": true,
+            "a": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "c"
+                              },
+                              {
+                                "tag": "a",
+                                "children": [
+                                  {
+                                    "text": "d"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "a",
+                            "children": [
+                              {
+                                "text": "e"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "f"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><i>a<b>b</b></i><b></b><div><b><i>c<a>d</a></i><a>e</a></b><a>f</a></div><table></table></body></html>",
+        "noQuirksBodyHtml": "<i>a<b>b</b></i><b></b><div><b><i>c<a>d</a></i><a>e</a></b><a>f</a></div><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><i>a<b>b<div>c<a>d</i>e</b>f",
+      "errors": [
+        "(1,37): adoption-agency-1.3",
+        "(1,37): adoption-agency-1.3",
+        "(1,42): adoption-agency-1.3",
+        "(1,42): adoption-agency-1.3",
+        "(1,43): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "i": true,
+            "b": true,
+            "div": true,
+            "a": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "c"
+                              },
+                              {
+                                "tag": "a",
+                                "children": [
+                                  {
+                                    "text": "d"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "a",
+                            "children": [
+                              {
+                                "text": "e"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "f"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><i>a<b>b</b></i><b></b><div><b><i>c<a>d</a></i><a>e</a></b><a>f</a></div></body></html>",
+        "noQuirksBodyHtml": "<i>a<b>b</b></i><b></b><div><b><i>c<a>d</a></i><a>e</a></b><a>f</a></div>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><i>a<b>b<div>c</i>",
+      "errors": [
+        "(1,25): foster-parenting-start-tag",
+        "(1,26): foster-parenting-character",
+        "(1,29): foster-parenting-start-tag",
+        "(1,30): foster-parenting-character",
+        "(1,35): foster-parenting-start-tag",
+        "(1,36): foster-parenting-character",
+        "(1,40): foster-parenting-end-tag",
+        "(1,40): adoption-agency-1.3",
+        "(1,40): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "i": true,
+            "b": true,
+            "div": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "c"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><i>a<b>b</b></i><b><div><i>c</i></div></b><table></table></body></html>",
+        "noQuirksBodyHtml": "<i>a<b>b</b></i><b><div><i>c</i></div></b><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f",
+      "errors": [
+        "(1,25): foster-parenting-start-tag",
+        "(1,26): foster-parenting-character",
+        "(1,29): foster-parenting-start-tag",
+        "(1,30): foster-parenting-character",
+        "(1,35): foster-parenting-start-tag",
+        "(1,36): foster-parenting-character",
+        "(1,39): foster-parenting-start-tag",
+        "(1,40): foster-parenting-character",
+        "(1,44): foster-parenting-end-tag",
+        "(1,44): adoption-agency-1.3",
+        "(1,44): adoption-agency-1.3",
+        "(1,45): foster-parenting-character",
+        "(1,49): foster-parenting-end-tag",
+        "(1,44): adoption-agency-1.3",
+        "(1,44): adoption-agency-1.3",
+        "(1,50): foster-parenting-character",
+        "(1,50): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "i": true,
+            "b": true,
+            "div": true,
+            "a": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "c"
+                              },
+                              {
+                                "tag": "a",
+                                "children": [
+                                  {
+                                    "text": "d"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "a",
+                            "children": [
+                              {
+                                "text": "e"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "f"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><i>a<b>b</b></i><b></b><div><b><i>c<a>d</a></i><a>e</a></b><a>f</a></div><table></table></body></html>",
+        "noQuirksBodyHtml": "<i>a<b>b</b></i><b></b><div><b><i>c<a>d</a></i><a>e</a></b><a>f</a></div><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><i>a<div>b<tr>c<b>d</i>e",
+      "errors": [
+        "(1,25): foster-parenting-start-tag",
+        "(1,26): foster-parenting-character",
+        "(1,31): foster-parenting-start-tag",
+        "(1,32): foster-parenting-character",
+        "(1,37): foster-parenting-character",
+        "(1,40): foster-parenting-start-tag",
+        "(1,41): foster-parenting-character",
+        "(1,45): foster-parenting-end-tag",
+        "(1,45): adoption-agency-1.3",
+        "(1,46): foster-parenting-character",
+        "(1,46): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "i": true,
+            "div": true,
+            "b": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": "c"
+                      },
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "d"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "e"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><i>a<div>b</div></i><i>c<b>d</b></i><b>e</b><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<i>a<div>b</div></i><i>c<b>d</b></i><b>e</b><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><td><table><i>a<div>b<b>c</i>d",
+      "errors": [
+        "(1,26): unexpected-cell-in-table-body",
+        "(1,36): foster-parenting-start-tag",
+        "(1,37): foster-parenting-character",
+        "(1,42): foster-parenting-start-tag",
+        "(1,43): foster-parenting-character",
+        "(1,46): foster-parenting-start-tag",
+        "(1,47): foster-parenting-character",
+        "(1,51): foster-parenting-end-tag",
+        "(1,51): adoption-agency-1.3",
+        "(1,51): adoption-agency-1.3",
+        "(1,52): foster-parenting-character",
+        "(1,52): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "i": true,
+            "div": true,
+            "b": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "i",
+                                    "children": [
+                                      {
+                                        "text": "a"
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "tag": "div",
+                                    "children": [
+                                      {
+                                        "tag": "i",
+                                        "children": [
+                                          {
+                                            "text": "b"
+                                          },
+                                          {
+                                            "tag": "b",
+                                            "children": [
+                                              {
+                                                "text": "c"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "b",
+                                        "children": [
+                                          {
+                                            "text": "d"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "tag": "table"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><i>a</i><div><i>b<b>c</b></i><b>d</b></div><table></table></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><i>a</i><div><i>b<b>c</b></i><b>d</b></div><table></table></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><body><bgsound>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "bgsound": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "bgsound"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><bgsound></body></html>",
+        "noQuirksBodyHtml": "<bgsound>"
+      }
+    },
+    {
+      "data": "<!doctype html><body><basefont>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "basefont": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "basefont"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><basefont></body></html>",
+        "noQuirksBodyHtml": "<basefont>"
+      }
+    },
+    {
+      "data": "<!doctype html><a><b></a><basefont>",
+      "errors": [
+        "(1,25): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true,
+            "basefont": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "basefont"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><a><b></b></a><basefont></body></html>",
+        "noQuirksBodyHtml": "<a><b></b></a><basefont>"
+      }
+    },
+    {
+      "data": "<!doctype html><a><b></a><bgsound>",
+      "errors": [
+        "(1,25): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true,
+            "bgsound": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "bgsound"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><a><b></b></a><bgsound></body></html>",
+        "noQuirksBodyHtml": "<a><b></b></a><bgsound>"
+      }
+    },
+    {
+      "data": "<!doctype html><figcaption><article></figcaption>a",
+      "errors": [
+        "(1,49): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "figcaption": true,
+            "article": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "figcaption",
+                    "children": [
+                      {
+                        "tag": "article"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><figcaption><article></article></figcaption>a</body></html>",
+        "noQuirksBodyHtml": "<figcaption><article></article></figcaption>a"
+      }
+    },
+    {
+      "data": "<!doctype html><summary><article></summary>a",
+      "errors": [
+        "(1,43): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "summary": true,
+            "article": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "summary",
+                    "children": [
+                      {
+                        "tag": "article"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><summary><article></article></summary>a</body></html>",
+        "noQuirksBodyHtml": "<summary><article></article></summary>a"
+      }
+    },
+    {
+      "data": "<!doctype html><p><a><plaintext>b",
+      "errors": [
+        "(1,32): unexpected-end-tag",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "a": true,
+            "plaintext": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><a></a></p><plaintext><a>b</a></plaintext></body></html>",
+        "noQuirksBodyHtml": "<p><a></a></p><plaintext><a>b</a></plaintext>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><div>a<a></div>b<p>c</p>d",
+      "errors": [
+        "(1,30): end-tag-too-early",
+        "(1,40): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "a": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "b"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "c"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "d"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><div>a<a></a></div><a>b<p>c</p>d</a></body></html>",
+        "noQuirksBodyHtml": "<div>a<a></a></div><a>b<p>c</p>d</a>"
+      }
+    }
+  ],
+  "tests2.dat": [
+    {
+      "data": "<!DOCTYPE html>Test",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Test"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>Test</body></html>",
+        "noQuirksBodyHtml": "Test"
+      }
+    },
+    {
+      "data": "<textarea>test</div>test",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,24): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "test</div>test",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><textarea>test&lt;/div&gt;test</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>test&lt;/div&gt;test</textarea>"
+      }
+    },
+    {
+      "data": "<table><td>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,11): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><td>test</tbody></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "test"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td>test</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td>test</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<frame>test",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,7): unexpected-start-tag-ignored"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "test"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>test</body></html>",
+        "noQuirksBodyHtml": "test"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><frameset>test",
+      "errors": [
+        "(1,29): unexpected-char-in-frameset",
+        "(1,29): unexpected-char-in-frameset",
+        "(1,29): unexpected-char-in-frameset",
+        "(1,29): unexpected-char-in-frameset",
+        "(1,29): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "test"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><frameset> te st",
+      "errors": [
+        "(1,29): unexpected-char-in-frameset",
+        "(1,29): unexpected-char-in-frameset",
+        "(1,29): unexpected-char-in-frameset",
+        "(1,29): unexpected-char-in-frameset",
+        "(1,29): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "text": "  "
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset>  </frameset></html>",
+        "noQuirksBodyHtml": " te st"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><frameset></frameset> te st",
+      "errors": [
+        "(1,29): unexpected-char-after-frameset",
+        "(1,29): unexpected-char-after-frameset",
+        "(1,29): unexpected-char-after-frameset",
+        "(1,29): unexpected-char-after-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "text": "  "
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset>  </html>",
+        "noQuirksBodyHtml": " te st"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><frameset><!DOCTYPE html>",
+      "errors": [
+        "(1,40): unexpected-doctype",
+        "(1,40): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><font><p><b>test</font>",
+      "errors": [
+        "(1,38): adoption-agency-1.3",
+        "(1,38): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "font": true,
+            "p": true,
+            "b": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "font"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "text": "test"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><font></font><p><font><b>test</b></font></p></body></html>",
+        "noQuirksBodyHtml": "<font></font><p><font><b>test</b></font></p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><dt><div><dd>",
+      "errors": [
+        "(1,28): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dt": true,
+            "div": true,
+            "dd": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dt",
+                    "children": [
+                      {
+                        "tag": "div"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "dd"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><dt><div></div></dt><dd></dd></body></html>",
+        "noQuirksBodyHtml": "<dt><div></div></dt><dd></dd>"
+      }
+    },
+    {
+      "data": "<script></x",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,11): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "</x",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></x</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></x</script>"
+      }
+    },
+    {
+      "data": "<table><plaintext><td>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,18): unexpected-start-tag-implies-table-voodoo",
+        "(1,22): foster-parenting-character-in-table",
+        "(1,22): foster-parenting-character-in-table",
+        "(1,22): foster-parenting-character-in-table",
+        "(1,22): foster-parenting-character-in-table",
+        "(1,22): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "plaintext": true,
+            "table": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "text": "<td>",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><plaintext><td></plaintext><table></table></body></html>",
+        "noQuirksBodyHtml": "<plaintext><td></plaintext><table></table>"
+      }
+    },
+    {
+      "data": "<plaintext></plaintext>",
+      "errors": [
+        "(1,11): expected-doctype-but-got-start-tag",
+        "(1,23): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "plaintext": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "text": "</plaintext>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><plaintext></plaintext></plaintext></body></html>",
+        "noQuirksBodyHtml": "<plaintext></plaintext></plaintext>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><table><tr>TEST",
+      "errors": [
+        "(1,30): foster-parenting-character-in-table",
+        "(1,30): foster-parenting-character-in-table",
+        "(1,30): foster-parenting-character-in-table",
+        "(1,30): foster-parenting-character-in-table",
+        "(1,30): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "TEST"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>TEST<table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "TEST<table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body t1=1><body t2=2><body t3=3 t4=4>",
+      "errors": [
+        "(1,37): unexpected-start-tag",
+        "(1,53): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "t1",
+                    "value": "1"
+                  },
+                  {
+                    "name": "t2",
+                    "value": "2"
+                  },
+                  {
+                    "name": "t3",
+                    "value": "3"
+                  },
+                  {
+                    "name": "t4",
+                    "value": "4"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body t1=\"1\" t2=\"2\" t3=\"3\" t4=\"4\"></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "</b test",
+      "errors": [
+        "(1,8): eof-in-attribute-name",
+        "(1,8): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html></b test<b &=&amp>X",
+      "errors": [
+        "(1,24): invalid-character-in-attribute-name",
+        "(1,32): named-entity-without-semicolon",
+        "(1,33): attributes-in-end-tag",
+        "(1,33): unexpected-end-tag-before-html"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>X</body></html>",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<!doctypehtml><scrIPt type=text/x-foobar;baz>X</SCRipt",
+      "errors": [
+        "(1,9): need-space-after-doctype",
+        "(1,54): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "text/x-foobar;baz"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "X</SCRipt",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script type=\"text/x-foobar;baz\">X</SCRipt</script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script type=\"text/x-foobar;baz\">X</SCRipt</script>"
+      }
+    },
+    {
+      "data": "&",
+      "errors": [
+        "(1,1): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "&",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&amp;</body></html>",
+        "noQuirksBodyHtml": "&amp;"
+      }
+    },
+    {
+      "data": "&#",
+      "errors": [
+        "(1,2): expected-numeric-entity",
+        "(1,2): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "&#",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&amp;#</body></html>",
+        "noQuirksBodyHtml": "&amp;#"
+      }
+    },
+    {
+      "data": "&#X",
+      "errors": [
+        "(1,3): expected-numeric-entity",
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "&#X",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&amp;#X</body></html>",
+        "noQuirksBodyHtml": "&amp;#X"
+      }
+    },
+    {
+      "data": "&#x",
+      "errors": [
+        "(1,3): expected-numeric-entity",
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "&#x",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&amp;#x</body></html>",
+        "noQuirksBodyHtml": "&amp;#x"
+      }
+    },
+    {
+      "data": "&#45",
+      "errors": [
+        "(1,4): numeric-entity-without-semicolon",
+        "(1,4): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>-</body></html>",
+        "noQuirksBodyHtml": "-"
+      }
+    },
+    {
+      "data": "&x-test",
+      "errors": [
+        "(1,2): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "&x-test",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&amp;x-test</body></html>",
+        "noQuirksBodyHtml": "&amp;x-test"
+      }
+    },
+    {
+      "data": "<!doctypehtml><p><li>",
+      "errors": [
+        "(1,9): need-space-after-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "li": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "li"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><li></li></body></html>",
+        "noQuirksBodyHtml": "<p></p><li></li>"
+      }
+    },
+    {
+      "data": "<!doctypehtml><p><dt>",
+      "errors": [
+        "(1,9): need-space-after-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "dt": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "dt"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><dt></dt></body></html>",
+        "noQuirksBodyHtml": "<p></p><dt></dt>"
+      }
+    },
+    {
+      "data": "<!doctypehtml><p><dd>",
+      "errors": [
+        "(1,9): need-space-after-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "dd": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "dd"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><dd></dd></body></html>",
+        "noQuirksBodyHtml": "<p></p><dd></dd>"
+      }
+    },
+    {
+      "data": "<!doctypehtml><p><form>",
+      "errors": [
+        "(1,9): need-space-after-doctype",
+        "(1,23): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "form": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "form"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><form></form></body></html>",
+        "noQuirksBodyHtml": "<p></p><form></form>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><p></P>X",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p>X</body></html>",
+        "noQuirksBodyHtml": "<p></p>X"
+      }
+    },
+    {
+      "data": "&AMP",
+      "errors": [
+        "(1,4): named-entity-without-semicolon",
+        "(1,4): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "&",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&amp;</body></html>",
+        "noQuirksBodyHtml": "&amp;"
+      }
+    },
+    {
+      "data": "&AMp;",
+      "errors": [
+        "(1,3): expected-named-entity",
+        "(1,3): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "&AMp;",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&amp;AMp;</body></html>",
+        "noQuirksBodyHtml": "&amp;AMp;"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><thisISasillyTESTelementNameToMakeSureCrazyTagNamesArePARSEDcorrectLY>",
+      "errors": [
+        "(1,110): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly></thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly></body></html>",
+        "noQuirksBodyHtml": "<thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly></thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>X</body>X",
+      "errors": [
+        "(1,24): unexpected-char-after-body"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "XX"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>XX</body></html>",
+        "noQuirksBodyHtml": "XX"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><!-- X",
+      "errors": [
+        "(1,21): eof-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "comment": " X"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><!-- X--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!-- X-->"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><table><caption>test TEST</caption><td>test",
+      "errors": [
+        "(1,54): unexpected-cell-in-table-body",
+        "(1,58): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "text": "test TEST"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "test"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption>test TEST</caption><tbody><tr><td>test</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption>test TEST</caption><tbody><tr><td>test</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><select><option><optgroup>",
+      "errors": [
+        "(1,41): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true,
+            "optgroup": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      },
+                      {
+                        "tag": "optgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><option></option><optgroup></optgroup></select></body></html>",
+        "noQuirksBodyHtml": "<select><option></option><optgroup></optgroup></select>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><select><optgroup><option></optgroup><option><select><option>",
+      "errors": [
+        "(1,68): unexpected-select-in-select",
+        "(1,76): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "optgroup": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "optgroup",
+                        "children": [
+                          {
+                            "tag": "option"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "option"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><optgroup><option></option></optgroup><option></option></select><option></option></body></html>",
+        "noQuirksBodyHtml": "<select><optgroup><option></option></optgroup><option></option></select><option></option>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><select><optgroup><option><optgroup>",
+      "errors": [
+        "(1,51): eof-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "optgroup": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "optgroup",
+                        "children": [
+                          {
+                            "tag": "option"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "optgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><optgroup><option></option></optgroup><optgroup></optgroup></select></body></html>",
+        "noQuirksBodyHtml": "<select><optgroup><option></option></optgroup><optgroup></optgroup></select>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><datalist><option>foo</datalist>bar",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "datalist": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "datalist",
+                    "children": [
+                      {
+                        "tag": "option",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "bar"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><datalist><option>foo</option></datalist>bar</body></html>",
+        "noQuirksBodyHtml": "<datalist><option>foo</option></datalist>bar"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><font><input><input></font>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "font": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "font",
+                    "children": [
+                      {
+                        "tag": "input"
+                      },
+                      {
+                        "tag": "input"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><font><input><input></font></body></html>",
+        "noQuirksBodyHtml": "<font><input><input></font>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><!-- XXX - XXX -->",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "comment": " XXX - XXX "
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><!-- XXX - XXX --><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!-- XXX - XXX -->"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><!-- XXX - XXX",
+      "errors": [
+        "(1,29): eof-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "comment": " XXX - XXX"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><!-- XXX - XXX--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!-- XXX - XXX-->"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><!-- XXX - XXX - XXX -->",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "comment": " XXX - XXX - XXX "
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><!-- XXX - XXX - XXX --><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!-- XXX - XXX - XXX -->"
+      }
+    },
+    {
+      "data": "<isindex test=x name=x>",
+      "errors": [
+        "(1,23): expected-doctype-but-got-start-tag",
+        "(1,23): deprecated-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "hr": true,
+            "label": true,
+            "input": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "hr"
+                      },
+                      {
+                        "tag": "label",
+                        "children": [
+                          {
+                            "text": "This is a searchable index. Enter search keywords: "
+                          },
+                          {
+                            "tag": "input",
+                            "attrs": [
+                              {
+                                "name": "name",
+                                "value": "isindex"
+                              },
+                              {
+                                "name": "test",
+                                "value": "x"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "hr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\" test=\"x\"></label><hr></form></body></html>",
+        "noQuirksBodyHtml": "<form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\" test=\"x\"></label><hr></form>"
+      }
+    },
+    {
+      "data": "test\ntest",
+      "errors": [
+        "(2,4): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "test\ntest"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>test\ntest</body></html>",
+        "noQuirksBodyHtml": "test\ntest"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><title>test</body></title>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "title": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "test</body>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><title>test&lt;/body&gt;</title></body></html>",
+        "noQuirksBodyHtml": "<title>test&lt;/body&gt;</title>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><title>X</title><meta name=z><link rel=foo><style>\nx { content:\"</style\" } </style>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "title": true,
+            "meta": true,
+            "link": true,
+            "style": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "meta",
+                    "attrs": [
+                      {
+                        "name": "name",
+                        "value": "z"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "link",
+                    "attrs": [
+                      {
+                        "name": "rel",
+                        "value": "foo"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": "\nx { content:\"</style\" } ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><title>X</title><meta name=\"z\"><link rel=\"foo\"><style>\nx { content:\"</style\" } </style></body></html>",
+        "noQuirksBodyHtml": "<title>X</title><meta name=\"z\"><link rel=\"foo\"><style>\nx { content:\"</style\" } </style>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><select><optgroup></optgroup></select>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "optgroup": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "optgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><optgroup></optgroup></select></body></html>",
+        "noQuirksBodyHtml": "<select><optgroup></optgroup></select>"
+      }
+    },
+    {
+      "data": " \n ",
+      "errors": [
+        "(2,1): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": " \n "
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>  <html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "  "
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><script>\n</script>  <title>x</title>  </head>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "title": true,
+            "body": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "\n",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "  "
+                  },
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "x"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "  "
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><script>\n</script>  <title>x</title>  </head><body></body></html>",
+        "noQuirksBodyHtml": "<script>\n</script>  <title>x</title>  "
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><body><html id=x>",
+      "errors": [
+        "(1,38): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "id",
+                "value": "x"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html id=\"x\"><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>X</body><html id=\"x\">",
+      "errors": [
+        "(1,36): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "id",
+                "value": "x"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html id=\"x\"><head></head><body>X</body></html>",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><head><html id=x>",
+      "errors": [
+        "(1,32): non-html-root"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "id",
+                "value": "x"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html id=\"x\"><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>X</html>X",
+      "errors": [
+        "(1,24): expected-eof-but-got-char"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "XX"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>XX</body></html>",
+        "noQuirksBodyHtml": "XX"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>X</html> ",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X "
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>X </body></html>",
+        "noQuirksBodyHtml": "X "
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>X</html><p>X",
+      "errors": [
+        "(1,26): expected-eof-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>X<p>X</p></body></html>",
+        "noQuirksBodyHtml": "X<p>X</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>X<p/x/y/z>",
+      "errors": [
+        "(1,19): unexpected-character-after-solidus-in-tag",
+        "(1,21): unexpected-character-after-solidus-in-tag",
+        "(1,23): unexpected-character-after-solidus-in-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  },
+                  {
+                    "tag": "p",
+                    "attrs": [
+                      {
+                        "name": "x",
+                        "value": ""
+                      },
+                      {
+                        "name": "y",
+                        "value": ""
+                      },
+                      {
+                        "name": "z",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>X<p x=\"\" y=\"\" z=\"\"></p></body></html>",
+        "noQuirksBodyHtml": "X<p x=\"\" y=\"\" z=\"\"></p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><!--x--",
+      "errors": [
+        "(1,22): eof-in-comment-double-dash"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "comment": "x"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><!--x--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!--x-->"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><table><tr><td></p></table>",
+      "errors": [
+        "(1,34): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "p"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><p></p></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><p></p></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE <!DOCTYPE HTML>><!--<!--x-->-->",
+      "errors": [
+        "(1,20): expected-space-or-right-bracket-in-doctype",
+        "(1,25): unknown-doctype",
+        "(1,35): unexpected-char-in-comment"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true,
+          "escaped": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "<!doctype"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": ">",
+                    "escaped": true
+                  },
+                  {
+                    "comment": "<!--x"
+                  },
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE <!doctype><html><head></head><body>&gt;<!--<!--x-->--&gt;</body></html>",
+        "noQuirksBodyHtml": "&gt;<!--<!--x-->--&gt;"
+      }
+    },
+    {
+      "data": "<!doctype html><div><form></form><div></div></div>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "form": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "form"
+                      },
+                      {
+                        "tag": "div"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><div><form></form><div></div></div></body></html>",
+        "noQuirksBodyHtml": "<div><form></form><div></div></div>"
+      }
+    }
+  ],
+  "tests20.dat": [
+    {
+      "data": "<!doctype html><p><button><button>",
+      "errors": [
+        "(1,34): unexpected-start-tag-implies-end-tag",
+        "(1,34): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button"
+                      },
+                      {
+                        "tag": "button"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button></button><button></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button></button><button></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><address>",
+      "errors": [
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "address": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "address"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><address></address></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><address></address></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><blockquote>",
+      "errors": [
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "blockquote": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "blockquote"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><blockquote></blockquote></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><blockquote></blockquote></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><menu>",
+      "errors": [
+        "(1,32): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "menu": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "menu"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><menu></menu></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><menu></menu></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><p>",
+      "errors": [
+        "(1,29): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "p"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><p></p></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><p></p></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><ul>",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "ul": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "ul"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><ul></ul></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><ul></ul></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><h1>",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "h1": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "h1"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><h1></h1></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><h1></h1></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><h6>",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "h6": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "h6"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><h6></h6></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><h6></h6></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><listing>",
+      "errors": [
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "listing": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "listing"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><listing></listing></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><listing></listing></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><pre>",
+      "errors": [
+        "(1,31): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "pre": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "pre"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><pre></pre></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><pre></pre></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><form>",
+      "errors": [
+        "(1,32): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "form": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "form"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><form></form></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><form></form></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><li>",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "li": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "li"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><li></li></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><li></li></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><dd>",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "dd": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "dd"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><dd></dd></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><dd></dd></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><dt>",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "dt": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "dt"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><dt></dt></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><dt></dt></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><plaintext>",
+      "errors": [
+        "(1,37): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "plaintext": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "plaintext"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><plaintext></plaintext></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><plaintext></plaintext></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><table>",
+      "errors": [
+        "(1,33): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "table"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><table></table></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><table></table></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><hr>",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "hr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "hr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><hr></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><hr></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button><xmp>",
+      "errors": [
+        "(1,31): expected-named-closing-tag-but-got-eof",
+        "(1,31): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true,
+            "xmp": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "xmp"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><xmp></xmp></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><xmp></xmp></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><button></p>",
+      "errors": [
+        "(1,30): unexpected-end-tag",
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "button": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "button",
+                        "children": [
+                          {
+                            "tag": "p"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><button><p></p></button></p></body></html>",
+        "noQuirksBodyHtml": "<p><button><p></p></button></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><address><button></address>a",
+      "errors": [
+        "(1,42): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "address": true,
+            "button": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "address",
+                    "children": [
+                      {
+                        "tag": "button"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><address><button></button></address>a</body></html>",
+        "noQuirksBodyHtml": "<address><button></button></address>a"
+      }
+    },
+    {
+      "data": "<!doctype html><address><button></address>a",
+      "errors": [
+        "(1,42): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "address": true,
+            "button": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "address",
+                    "children": [
+                      {
+                        "tag": "button"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><address><button></button></address>a</body></html>",
+        "noQuirksBodyHtml": "<address><button></button></address>a"
+      }
+    },
+    {
+      "data": "<p><table></p>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-end-tag-implies-table-voodoo",
+        "(1,14): unexpected-end-tag",
+        "(1,14): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "p"
+                      },
+                      {
+                        "tag": "table"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><p></p><table></table></p></body></html>",
+        "noQuirksBodyHtml": "<p></p><p></p><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><svg>",
+      "errors": [
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg></svg></body></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><figcaption>",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "figcaption": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "figcaption"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><figcaption></figcaption></body></html>",
+        "noQuirksBodyHtml": "<p></p><figcaption></figcaption>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><summary>",
+      "errors": [
+        "(1,27): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "summary": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "summary"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><summary></summary></body></html>",
+        "noQuirksBodyHtml": "<p></p><summary></summary>"
+      }
+    },
+    {
+      "data": "<!doctype html><form><table><form>",
+      "errors": [
+        "(1,34): unexpected-form-in-table",
+        "(1,34): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "table"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><form><table></table></form></body></html>",
+        "noQuirksBodyHtml": "<form><table></table></form>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><form><form>",
+      "errors": [
+        "(1,28): unexpected-form-in-table",
+        "(1,34): unexpected-form-in-table",
+        "(1,34): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "form": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "form"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><form></form></table></body></html>",
+        "noQuirksBodyHtml": "<table><form></form></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><form></table><form>",
+      "errors": [
+        "(1,28): unexpected-form-in-table",
+        "(1,42): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "form": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "form"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><form></form></table></body></html>",
+        "noQuirksBodyHtml": "<table><form></form></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><svg><foreignObject><p>",
+      "errors": [
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "p"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><foreignObject><p></p></foreignObject></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><foreignObject><p></p></foreignObject></svg>"
+      }
+    },
+    {
+      "data": "<!doctype html><svg><title>abc",
+      "errors": [
+        "(1,30): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg title": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "title",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "text": "abc"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><title>abc</title></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><title>abc</title></svg>"
+      }
+    },
+    {
+      "data": "<option><span><option>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,22): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "option": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "option",
+                    "children": [
+                      {
+                        "tag": "span",
+                        "children": [
+                          {
+                            "tag": "option"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><option><span><option></option></span></option></body></html>",
+        "noQuirksBodyHtml": "<option><span><option></option></span></option>"
+      }
+    },
+    {
+      "data": "<option><option>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "option"
+                  },
+                  {
+                    "tag": "option"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><option></option><option></option></body></html>",
+        "noQuirksBodyHtml": "<option></option><option></option>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,27): unexpected-html-element-in-foreign-content",
+        "(1,27): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml></annotation-xml></math><div></div></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"application/svg+xml\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,58): unexpected-html-element-in-foreign-content",
+        "(1,58): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "application/svg+xml"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"application/svg+xml\"></annotation-xml></math><div></div></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"application/svg+xml\"><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"application/xhtml+xml\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,60): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "application/xhtml+xml"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"application/xhtml+xml\"><div></div></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"application/xhtml+xml\"><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,60): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "aPPlication/xhtmL+xMl"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div></div></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"text/html\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,48): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "text/html"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"text/html\"><div></div></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"text/html\"><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"Text/htmL\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,48): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "Text/htmL"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"Text/htmL\"><div></div></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"Text/htmL\"><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\" text/html \"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,50): unexpected-html-element-in-foreign-content",
+        "(1,50): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": " text/html "
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\" text/html \"></annotation-xml></math><div></div></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\" text/html \"><div></div></annotation-xml></math>"
+      }
+    }
+  ],
+  "tests21.dat": [
+    {
+      "data": "<svg><![CDATA[foo]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>foo</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo</svg>"
+      }
+    },
+    {
+      "data": "<math><![CDATA[foo]]>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math>foo</math></body></html>",
+        "noQuirksBodyHtml": "<math>foo</math>"
+      }
+    },
+    {
+      "data": "<div><![CDATA[foo]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,7): expected-dashes-or-doctype",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "comment": "[CDATA[foo]]"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><!--[CDATA[foo]]--></div></body></html>",
+        "noQuirksBodyHtml": "<div><!--[CDATA[foo]]--></div>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[foo",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>foo</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[foo",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>foo</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,14): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg></body></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg></body></html>",
+        "noQuirksBodyHtml": "<svg></svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[]] >]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "]] >",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>]] &gt;</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>]] &gt;</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[]] >]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "]] >",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>]] &gt;</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>]] &gt;</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[]]",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "]]"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>]]</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>]]</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[]",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "]"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>]</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>]</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[]>a",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "]>a",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>]&gt;a</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>]&gt;a</svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><svg><![CDATA[foo]]]>",
+      "errors": [
+        "(1,36): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo]"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg>foo]</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo]</svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><svg><![CDATA[foo]]]]>",
+      "errors": [
+        "(1,37): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo]]"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg>foo]]</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo]]</svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><svg><![CDATA[foo]]]]]>",
+      "errors": [
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "foo]]]"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg>foo]]]</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>foo]]]</svg>"
+      }
+    },
+    {
+      "data": "<svg><foreignObject><div><![CDATA[foo]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,27): expected-dashes-or-doctype",
+        "(1,40): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "div": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "comment": "[CDATA[foo]]"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><foreignObject><div><!--[CDATA[foo]]--></div></foreignObject></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><foreignObject><div><!--[CDATA[foo]]--></div></foreignObject></svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[<svg>]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,22): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "<svg>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;svg&gt;</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;svg&gt;</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[</svg>a]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,24): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "</svg>a",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;/svg&gt;a</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;/svg&gt;a</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[<svg>a",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "<svg>a",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;svg&gt;a</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;svg&gt;a</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[</svg>a",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "</svg>a",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;/svg&gt;a</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;/svg&gt;a</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[<svg>]]><path>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,28): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg path": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "<svg>",
+                        "escaped": true
+                      },
+                      {
+                        "tag": "path",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;svg&gt;<path></path></svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;svg&gt;<path></path></svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[<svg>]]></path>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,29): unexpected-end-tag",
+        "(1,29): unexpected-end-tag",
+        "(1,29): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "<svg>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;svg&gt;</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;svg&gt;</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[<svg>]]><!--path-->",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "<svg>",
+                        "escaped": true
+                      },
+                      {
+                        "comment": "path"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;svg&gt;<!--path--></svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;svg&gt;<!--path--></svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[<svg>]]>path",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,26): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "<svg>path",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;svg&gt;path</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;svg&gt;path</svg>"
+      }
+    },
+    {
+      "data": "<svg><![CDATA[<!--svg-->]]>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,27): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "text": "<!--svg-->",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg>&lt;!--svg--&gt;</svg></body></html>",
+        "noQuirksBodyHtml": "<svg>&lt;!--svg--&gt;</svg>"
+      }
+    }
+  ],
+  "tests22.dat": [
+    {
+      "data": "<a><b><big><em><strong><div>X</a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,33): adoption-agency-1.3",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true,
+            "big": true,
+            "em": true,
+            "strong": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "big",
+                            "children": [
+                              {
+                                "tag": "em",
+                                "children": [
+                                  {
+                                    "tag": "strong"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "big",
+                    "children": [
+                      {
+                        "tag": "em",
+                        "children": [
+                          {
+                            "tag": "strong",
+                            "children": [
+                              {
+                                "tag": "div",
+                                "children": [
+                                  {
+                                    "tag": "a",
+                                    "children": [
+                                      {
+                                        "text": "X"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><b><big><em><strong></strong></em></big></b></a><big><em><strong><div><a>X</a></div></strong></em></big></body></html>",
+        "noQuirksBodyHtml": "<a><b><big><em><strong></strong></em></big></b></a><big><em><strong><div><a>X</a></div></strong></em></big>"
+      }
+    },
+    {
+      "data": "<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8>A</a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,91): adoption-agency-1.3",
+        "(1,91): adoption-agency-1.3",
+        "(1,91): adoption-agency-1.3",
+        "(1,91): adoption-agency-1.3",
+        "(1,91): adoption-agency-1.3",
+        "(1,91): adoption-agency-1.3",
+        "(1,91): adoption-agency-1.3",
+        "(1,91): adoption-agency-1.3",
+        "(1,91): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "1"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "a"
+                          },
+                          {
+                            "tag": "div",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "2"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "a"
+                              },
+                              {
+                                "tag": "div",
+                                "attrs": [
+                                  {
+                                    "name": "id",
+                                    "value": "3"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "a"
+                                  },
+                                  {
+                                    "tag": "div",
+                                    "attrs": [
+                                      {
+                                        "name": "id",
+                                        "value": "4"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "tag": "a"
+                                      },
+                                      {
+                                        "tag": "div",
+                                        "attrs": [
+                                          {
+                                            "name": "id",
+                                            "value": "5"
+                                          }
+                                        ],
+                                        "children": [
+                                          {
+                                            "tag": "a"
+                                          },
+                                          {
+                                            "tag": "div",
+                                            "attrs": [
+                                              {
+                                                "name": "id",
+                                                "value": "6"
+                                              }
+                                            ],
+                                            "children": [
+                                              {
+                                                "tag": "a"
+                                              },
+                                              {
+                                                "tag": "div",
+                                                "attrs": [
+                                                  {
+                                                    "name": "id",
+                                                    "value": "7"
+                                                  }
+                                                ],
+                                                "children": [
+                                                  {
+                                                    "tag": "a"
+                                                  },
+                                                  {
+                                                    "tag": "div",
+                                                    "attrs": [
+                                                      {
+                                                        "name": "id",
+                                                        "value": "8"
+                                                      }
+                                                    ],
+                                                    "children": [
+                                                      {
+                                                        "tag": "a",
+                                                        "children": [
+                                                          {
+                                                            "text": "A"
+                                                          }
+                                                        ]
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><b></b></a><b><div id=\"1\"><a></a><div id=\"2\"><a></a><div id=\"3\"><a></a><div id=\"4\"><a></a><div id=\"5\"><a></a><div id=\"6\"><a></a><div id=\"7\"><a></a><div id=\"8\"><a>A</a></div></div></div></div></div></div></div></div></b></body></html>",
+        "noQuirksBodyHtml": "<a><b></b></a><b><div id=\"1\"><a></a><div id=\"2\"><a></a><div id=\"3\"><a></a><div id=\"4\"><a></a><div id=\"5\"><a></a><div id=\"6\"><a></a><div id=\"7\"><a></a><div id=\"8\"><a>A</a></div></div></div></div></div></div></div></div></b>"
+      }
+    },
+    {
+      "data": "<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8><div id=9>A</a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,101): adoption-agency-1.3",
+        "(1,101): adoption-agency-1.3",
+        "(1,101): adoption-agency-1.3",
+        "(1,101): adoption-agency-1.3",
+        "(1,101): adoption-agency-1.3",
+        "(1,101): adoption-agency-1.3",
+        "(1,101): adoption-agency-1.3",
+        "(1,101): adoption-agency-1.3",
+        "(1,101): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "1"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "a"
+                          },
+                          {
+                            "tag": "div",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "2"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "a"
+                              },
+                              {
+                                "tag": "div",
+                                "attrs": [
+                                  {
+                                    "name": "id",
+                                    "value": "3"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "a"
+                                  },
+                                  {
+                                    "tag": "div",
+                                    "attrs": [
+                                      {
+                                        "name": "id",
+                                        "value": "4"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "tag": "a"
+                                      },
+                                      {
+                                        "tag": "div",
+                                        "attrs": [
+                                          {
+                                            "name": "id",
+                                            "value": "5"
+                                          }
+                                        ],
+                                        "children": [
+                                          {
+                                            "tag": "a"
+                                          },
+                                          {
+                                            "tag": "div",
+                                            "attrs": [
+                                              {
+                                                "name": "id",
+                                                "value": "6"
+                                              }
+                                            ],
+                                            "children": [
+                                              {
+                                                "tag": "a"
+                                              },
+                                              {
+                                                "tag": "div",
+                                                "attrs": [
+                                                  {
+                                                    "name": "id",
+                                                    "value": "7"
+                                                  }
+                                                ],
+                                                "children": [
+                                                  {
+                                                    "tag": "a"
+                                                  },
+                                                  {
+                                                    "tag": "div",
+                                                    "attrs": [
+                                                      {
+                                                        "name": "id",
+                                                        "value": "8"
+                                                      }
+                                                    ],
+                                                    "children": [
+                                                      {
+                                                        "tag": "a",
+                                                        "children": [
+                                                          {
+                                                            "tag": "div",
+                                                            "attrs": [
+                                                              {
+                                                                "name": "id",
+                                                                "value": "9"
+                                                              }
+                                                            ],
+                                                            "children": [
+                                                              {
+                                                                "text": "A"
+                                                              }
+                                                            ]
+                                                          }
+                                                        ]
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><b></b></a><b><div id=\"1\"><a></a><div id=\"2\"><a></a><div id=\"3\"><a></a><div id=\"4\"><a></a><div id=\"5\"><a></a><div id=\"6\"><a></a><div id=\"7\"><a></a><div id=\"8\"><a><div id=\"9\">A</div></a></div></div></div></div></div></div></div></div></b></body></html>",
+        "noQuirksBodyHtml": "<a><b></b></a><b><div id=\"1\"><a></a><div id=\"2\"><a></a><div id=\"3\"><a></a><div id=\"4\"><a></a><div id=\"5\"><a></a><div id=\"6\"><a></a><div id=\"7\"><a></a><div id=\"8\"><a><div id=\"9\">A</div></a></div></div></div></div></div></div></div></div></b>"
+      }
+    },
+    {
+      "data": "<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8><div id=9><div id=10>A</a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,112): adoption-agency-1.3",
+        "(1,112): adoption-agency-1.3",
+        "(1,112): adoption-agency-1.3",
+        "(1,112): adoption-agency-1.3",
+        "(1,112): adoption-agency-1.3",
+        "(1,112): adoption-agency-1.3",
+        "(1,112): adoption-agency-1.3",
+        "(1,112): adoption-agency-1.3",
+        "(1,112): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "b": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "1"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "a"
+                          },
+                          {
+                            "tag": "div",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "2"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "a"
+                              },
+                              {
+                                "tag": "div",
+                                "attrs": [
+                                  {
+                                    "name": "id",
+                                    "value": "3"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "a"
+                                  },
+                                  {
+                                    "tag": "div",
+                                    "attrs": [
+                                      {
+                                        "name": "id",
+                                        "value": "4"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "tag": "a"
+                                      },
+                                      {
+                                        "tag": "div",
+                                        "attrs": [
+                                          {
+                                            "name": "id",
+                                            "value": "5"
+                                          }
+                                        ],
+                                        "children": [
+                                          {
+                                            "tag": "a"
+                                          },
+                                          {
+                                            "tag": "div",
+                                            "attrs": [
+                                              {
+                                                "name": "id",
+                                                "value": "6"
+                                              }
+                                            ],
+                                            "children": [
+                                              {
+                                                "tag": "a"
+                                              },
+                                              {
+                                                "tag": "div",
+                                                "attrs": [
+                                                  {
+                                                    "name": "id",
+                                                    "value": "7"
+                                                  }
+                                                ],
+                                                "children": [
+                                                  {
+                                                    "tag": "a"
+                                                  },
+                                                  {
+                                                    "tag": "div",
+                                                    "attrs": [
+                                                      {
+                                                        "name": "id",
+                                                        "value": "8"
+                                                      }
+                                                    ],
+                                                    "children": [
+                                                      {
+                                                        "tag": "a",
+                                                        "children": [
+                                                          {
+                                                            "tag": "div",
+                                                            "attrs": [
+                                                              {
+                                                                "name": "id",
+                                                                "value": "9"
+                                                              }
+                                                            ],
+                                                            "children": [
+                                                              {
+                                                                "tag": "div",
+                                                                "attrs": [
+                                                                  {
+                                                                    "name": "id",
+                                                                    "value": "10"
+                                                                  }
+                                                                ],
+                                                                "children": [
+                                                                  {
+                                                                    "text": "A"
+                                                                  }
+                                                                ]
+                                                              }
+                                                            ]
+                                                          }
+                                                        ]
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a><b></b></a><b><div id=\"1\"><a></a><div id=\"2\"><a></a><div id=\"3\"><a></a><div id=\"4\"><a></a><div id=\"5\"><a></a><div id=\"6\"><a></a><div id=\"7\"><a></a><div id=\"8\"><a><div id=\"9\"><div id=\"10\">A</div></div></a></div></div></div></div></div></div></div></div></b></body></html>",
+        "noQuirksBodyHtml": "<a><b></b></a><b><div id=\"1\"><a></a><div id=\"2\"><a></a><div id=\"3\"><a></a><div id=\"4\"><a></a><div id=\"5\"><a></a><div id=\"6\"><a></a><div id=\"7\"><a></a><div id=\"8\"><a><div id=\"9\"><div id=\"10\">A</div></div></a></div></div></div></div></div></div></div></div></b>"
+      }
+    },
+    {
+      "data": "<cite><b><cite><i><cite><i><cite><i><div>X</b>TEST",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,46): adoption-agency-1.3",
+        "(1,50): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "cite": true,
+            "b": true,
+            "i": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "cite",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "cite",
+                            "children": [
+                              {
+                                "tag": "i",
+                                "children": [
+                                  {
+                                    "tag": "cite",
+                                    "children": [
+                                      {
+                                        "tag": "i",
+                                        "children": [
+                                          {
+                                            "tag": "cite",
+                                            "children": [
+                                              {
+                                                "tag": "i"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "div",
+                                "children": [
+                                  {
+                                    "tag": "b",
+                                    "children": [
+                                      {
+                                        "text": "X"
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "text": "TEST"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><cite><b><cite><i><cite><i><cite><i></i></cite></i></cite></i></cite></b><i><i><div><b>X</b>TEST</div></i></i></cite></body></html>",
+        "noQuirksBodyHtml": "<cite><b><cite><i><cite><i><cite><i></i></cite></i></cite></i></cite></b><i><i><div><b>X</b>TEST</div></i></i></cite>"
+      }
+    }
+  ],
+  "tests23.dat": [
+    {
+      "data": "<p><font size=4><font color=red><font size=4><font size=4><font size=4><font size=4><font size=4><font color=red><p>X",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,116): unexpected-end-tag",
+        "(1,117): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "size",
+                            "value": "4"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "color",
+                                "value": "red"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "font",
+                                "attrs": [
+                                  {
+                                    "name": "size",
+                                    "value": "4"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "font",
+                                    "attrs": [
+                                      {
+                                        "name": "size",
+                                        "value": "4"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "tag": "font",
+                                        "attrs": [
+                                          {
+                                            "name": "size",
+                                            "value": "4"
+                                          }
+                                        ],
+                                        "children": [
+                                          {
+                                            "tag": "font",
+                                            "attrs": [
+                                              {
+                                                "name": "size",
+                                                "value": "4"
+                                              }
+                                            ],
+                                            "children": [
+                                              {
+                                                "tag": "font",
+                                                "attrs": [
+                                                  {
+                                                    "name": "size",
+                                                    "value": "4"
+                                                  }
+                                                ],
+                                                "children": [
+                                                  {
+                                                    "tag": "font",
+                                                    "attrs": [
+                                                      {
+                                                        "name": "color",
+                                                        "value": "red"
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "color",
+                            "value": "red"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "size",
+                                "value": "4"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "font",
+                                "attrs": [
+                                  {
+                                    "name": "size",
+                                    "value": "4"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "font",
+                                    "attrs": [
+                                      {
+                                        "name": "size",
+                                        "value": "4"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "tag": "font",
+                                        "attrs": [
+                                          {
+                                            "name": "color",
+                                            "value": "red"
+                                          }
+                                        ],
+                                        "children": [
+                                          {
+                                            "text": "X"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><font size=\"4\"><font color=\"red\"><font size=\"4\"><font size=\"4\"><font size=\"4\"><font size=\"4\"><font size=\"4\"><font color=\"red\"></font></font></font></font></font></font></font></font></p><p><font color=\"red\"><font size=\"4\"><font size=\"4\"><font size=\"4\"><font color=\"red\">X</font></font></font></font></font></p></body></html>",
+        "noQuirksBodyHtml": "<p><font size=\"4\"><font color=\"red\"><font size=\"4\"><font size=\"4\"><font size=\"4\"><font size=\"4\"><font size=\"4\"><font color=\"red\"></font></font></font></font></font></font></font></font></p><p><font color=\"red\"><font size=\"4\"><font size=\"4\"><font size=\"4\"><font color=\"red\">X</font></font></font></font></font></p>"
+      }
+    },
+    {
+      "data": "<p><font size=4><font size=4><font size=4><font size=4><p>X",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,58): unexpected-end-tag",
+        "(1,59): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "size",
+                            "value": "4"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "size",
+                                "value": "4"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "font",
+                                "attrs": [
+                                  {
+                                    "name": "size",
+                                    "value": "4"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "font",
+                                    "attrs": [
+                                      {
+                                        "name": "size",
+                                        "value": "4"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "size",
+                            "value": "4"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "size",
+                                "value": "4"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "font",
+                                "attrs": [
+                                  {
+                                    "name": "size",
+                                    "value": "4"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "text": "X"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><font size=\"4\"><font size=\"4\"><font size=\"4\"><font size=\"4\"></font></font></font></font></p><p><font size=\"4\"><font size=\"4\"><font size=\"4\">X</font></font></font></p></body></html>",
+        "noQuirksBodyHtml": "<p><font size=\"4\"><font size=\"4\"><font size=\"4\"><font size=\"4\"></font></font></font></font></p><p><font size=\"4\"><font size=\"4\"><font size=\"4\">X</font></font></font></p>"
+      }
+    },
+    {
+      "data": "<p><font size=4><font size=4><font size=4><font size=\"5\"><font size=4><p>X",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,73): unexpected-end-tag",
+        "(1,74): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "size",
+                            "value": "4"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "size",
+                                "value": "4"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "font",
+                                "attrs": [
+                                  {
+                                    "name": "size",
+                                    "value": "4"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "font",
+                                    "attrs": [
+                                      {
+                                        "name": "size",
+                                        "value": "5"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "tag": "font",
+                                        "attrs": [
+                                          {
+                                            "name": "size",
+                                            "value": "4"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "size",
+                            "value": "4"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "size",
+                                "value": "4"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "font",
+                                "attrs": [
+                                  {
+                                    "name": "size",
+                                    "value": "5"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "font",
+                                    "attrs": [
+                                      {
+                                        "name": "size",
+                                        "value": "4"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "text": "X"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><font size=\"4\"><font size=\"4\"><font size=\"4\"><font size=\"5\"><font size=\"4\"></font></font></font></font></font></p><p><font size=\"4\"><font size=\"4\"><font size=\"5\"><font size=\"4\">X</font></font></font></font></p></body></html>",
+        "noQuirksBodyHtml": "<p><font size=\"4\"><font size=\"4\"><font size=\"4\"><font size=\"5\"><font size=\"4\"></font></font></font></font></font></p><p><font size=\"4\"><font size=\"4\"><font size=\"5\"><font size=\"4\">X</font></font></font></font></p>"
+      }
+    },
+    {
+      "data": "<p><font size=4 id=a><font size=4 id=b><font size=4><font size=4><p>X",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,68): unexpected-end-tag",
+        "(1,69): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "font": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "a"
+                          },
+                          {
+                            "name": "size",
+                            "value": "4"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "b"
+                              },
+                              {
+                                "name": "size",
+                                "value": "4"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "font",
+                                "attrs": [
+                                  {
+                                    "name": "size",
+                                    "value": "4"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "font",
+                                    "attrs": [
+                                      {
+                                        "name": "size",
+                                        "value": "4"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "a"
+                          },
+                          {
+                            "name": "size",
+                            "value": "4"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "b"
+                              },
+                              {
+                                "name": "size",
+                                "value": "4"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "font",
+                                "attrs": [
+                                  {
+                                    "name": "size",
+                                    "value": "4"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "font",
+                                    "attrs": [
+                                      {
+                                        "name": "size",
+                                        "value": "4"
+                                      }
+                                    ],
+                                    "children": [
+                                      {
+                                        "text": "X"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><font size=\"4\" id=\"a\"><font size=\"4\" id=\"b\"><font size=\"4\"><font size=\"4\"></font></font></font></font></p><p><font size=\"4\" id=\"a\"><font size=\"4\" id=\"b\"><font size=\"4\"><font size=\"4\">X</font></font></font></font></p></body></html>",
+        "noQuirksBodyHtml": "<p><font size=\"4\" id=\"a\"><font size=\"4\" id=\"b\"><font size=\"4\"><font size=\"4\"></font></font></font></font></p><p><font size=\"4\" id=\"a\"><font size=\"4\" id=\"b\"><font size=\"4\"><font size=\"4\">X</font></font></font></font></p>"
+      }
+    },
+    {
+      "data": "<p><b id=a><b id=a><b id=a><b><object><b id=a><b id=a>X</object><p>Y",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,64): end-tag-too-early",
+        "(1,67): unexpected-end-tag",
+        "(1,68): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "b": true,
+            "object": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "a"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "b",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "a"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "b",
+                                "attrs": [
+                                  {
+                                    "name": "id",
+                                    "value": "a"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "b",
+                                    "children": [
+                                      {
+                                        "tag": "object",
+                                        "children": [
+                                          {
+                                            "tag": "b",
+                                            "attrs": [
+                                              {
+                                                "name": "id",
+                                                "value": "a"
+                                              }
+                                            ],
+                                            "children": [
+                                              {
+                                                "tag": "b",
+                                                "attrs": [
+                                                  {
+                                                    "name": "id",
+                                                    "value": "a"
+                                                  }
+                                                ],
+                                                "children": [
+                                                  {
+                                                    "text": "X"
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "attrs": [
+                          {
+                            "name": "id",
+                            "value": "a"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "b",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "a"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "tag": "b",
+                                "attrs": [
+                                  {
+                                    "name": "id",
+                                    "value": "a"
+                                  }
+                                ],
+                                "children": [
+                                  {
+                                    "tag": "b",
+                                    "children": [
+                                      {
+                                        "text": "Y"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><b id=\"a\"><b id=\"a\"><b id=\"a\"><b><object><b id=\"a\"><b id=\"a\">X</b></b></object></b></b></b></b></p><p><b id=\"a\"><b id=\"a\"><b id=\"a\"><b>Y</b></b></b></b></p></body></html>",
+        "noQuirksBodyHtml": "<p><b id=\"a\"><b id=\"a\"><b id=\"a\"><b><object><b id=\"a\"><b id=\"a\">X</b></b></object></b></b></b></b></p><p><b id=\"a\"><b id=\"a\"><b id=\"a\"><b>Y</b></b></b></b></p>"
+      }
+    }
+  ],
+  "tests24.dat": [
+    {
+      "data": "<!DOCTYPE html>&NotEqualTilde;",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "≂̸"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>≂̸</body></html>",
+        "noQuirksBodyHtml": "≂̸"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>&NotEqualTilde;A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "≂̸A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>≂̸A</body></html>",
+        "noQuirksBodyHtml": "≂̸A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>&ThickSpace;",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "  "
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>  </body></html>",
+        "noQuirksBodyHtml": "  "
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>&ThickSpace;A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "  A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>  A</body></html>",
+        "noQuirksBodyHtml": "  A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>&NotSubset;",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "⊂⃒"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>⊂⃒</body></html>",
+        "noQuirksBodyHtml": "⊂⃒"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>&NotSubset;A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "⊂⃒A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>⊂⃒A</body></html>",
+        "noQuirksBodyHtml": "⊂⃒A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>&Gopf;",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "𝔾"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>𝔾</body></html>",
+        "noQuirksBodyHtml": "𝔾"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>&Gopf;A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "𝔾A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>𝔾A</body></html>",
+        "noQuirksBodyHtml": "𝔾A"
+      }
+    }
+  ],
+  "tests25.dat": [
+    {
+      "data": "<!DOCTYPE html><body><foo>A",
+      "errors": [
+        "(1,27): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "foo": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "children": [
+                      {
+                        "text": "A"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><foo>A</foo></body></html>",
+        "noQuirksBodyHtml": "<foo>A</foo>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><area>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "area": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "area"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><area>A</body></html>",
+        "noQuirksBodyHtml": "<area>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><base>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "base": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "base"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><base>A</body></html>",
+        "noQuirksBodyHtml": "<base>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><basefont>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "basefont": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "basefont"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><basefont>A</body></html>",
+        "noQuirksBodyHtml": "<basefont>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><bgsound>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "bgsound": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "bgsound"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><bgsound>A</body></html>",
+        "noQuirksBodyHtml": "<bgsound>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><br>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "br": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "br"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><br>A</body></html>",
+        "noQuirksBodyHtml": "<br>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><col>A",
+      "errors": [
+        "(1,26): unexpected-start-tag-ignored"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>A</body></html>",
+        "noQuirksBodyHtml": "A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><command>A",
+      "errors": [
+        "eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "command": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "command",
+                    "children": [
+                      {
+                        "text": "A"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><command>A</command></body></html>",
+        "noQuirksBodyHtml": "<command>A</command>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><menuitem>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem>A</body></html>",
+        "noQuirksBodyHtml": "<menuitem>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><embed>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "embed": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "embed"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><embed>A</body></html>",
+        "noQuirksBodyHtml": "<embed>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><frame>A",
+      "errors": [
+        "(1,28): unexpected-start-tag-ignored"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>A</body></html>",
+        "noQuirksBodyHtml": "A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><hr>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "hr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "hr"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><hr>A</body></html>",
+        "noQuirksBodyHtml": "<hr>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><img>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "img": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "img"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><img>A</body></html>",
+        "noQuirksBodyHtml": "<img>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><input>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "input"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><input>A</body></html>",
+        "noQuirksBodyHtml": "<input>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><keygen>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "keygen": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "keygen"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><keygen>A</body></html>",
+        "noQuirksBodyHtml": "<keygen>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><link>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "link": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "link"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><link>A</body></html>",
+        "noQuirksBodyHtml": "<link>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><meta>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "meta": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "meta"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><meta>A</body></html>",
+        "noQuirksBodyHtml": "<meta>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><param>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "param": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "param"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><param>A</body></html>",
+        "noQuirksBodyHtml": "<param>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><source>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "source": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "source"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><source>A</body></html>",
+        "noQuirksBodyHtml": "<source>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><track>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "track": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "track"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><track>A</body></html>",
+        "noQuirksBodyHtml": "<track>A"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><wbr>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "wbr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "wbr"
+                  },
+                  {
+                    "text": "A"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><wbr>A</body></html>",
+        "noQuirksBodyHtml": "<wbr>A"
+      }
+    }
+  ],
+  "tests26.dat": [
+    {
+      "data": "<!DOCTYPE html><body><a href='#1'><nobr>1<nobr></a><br><a href='#2'><nobr>2<nobr></a><br><a href='#3'><nobr>3<nobr></a>",
+      "errors": [
+        "(1,47): unexpected-start-tag-implies-end-tag",
+        "(1,51): adoption-agency-1.3",
+        "(1,74): unexpected-start-tag-implies-end-tag",
+        "(1,74): adoption-agency-1.3",
+        "(1,81): unexpected-start-tag-implies-end-tag",
+        "(1,85): adoption-agency-1.3",
+        "(1,108): unexpected-start-tag-implies-end-tag",
+        "(1,108): adoption-agency-1.3",
+        "(1,115): unexpected-start-tag-implies-end-tag",
+        "(1,119): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "nobr": true,
+            "br": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "#1"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "1"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "nobr",
+                    "children": [
+                      {
+                        "tag": "br"
+                      },
+                      {
+                        "tag": "a",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "value": "#2"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "#2"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "nobr",
+                    "children": [
+                      {
+                        "tag": "br"
+                      },
+                      {
+                        "tag": "a",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "value": "#3"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "value": "#3"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "3"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><a href=\"#1\"><nobr>1</nobr><nobr></nobr></a><nobr><br><a href=\"#2\"></a></nobr><a href=\"#2\"><nobr>2</nobr><nobr></nobr></a><nobr><br><a href=\"#3\"></a></nobr><a href=\"#3\"><nobr>3</nobr><nobr></nobr></a></body></html>",
+        "noQuirksBodyHtml": "<a href=\"#1\"><nobr>1</nobr><nobr></nobr></a><nobr><br><a href=\"#2\"></a></nobr><a href=\"#2\"><nobr>2</nobr><nobr></nobr></a><nobr><br><a href=\"#3\"></a></nobr><a href=\"#3\"><nobr>3</nobr><nobr></nobr></a>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><b><nobr>1<nobr></b><i><nobr>2<nobr></i>3",
+      "errors": [
+        "(1,37): unexpected-start-tag-implies-end-tag",
+        "(1,41): adoption-agency-1.3",
+        "(1,50): unexpected-start-tag-implies-end-tag",
+        "(1,50): adoption-agency-1.3",
+        "(1,57): unexpected-start-tag-implies-end-tag",
+        "(1,61): adoption-agency-1.3",
+        "(1,62): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "1"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "nobr",
+                    "children": [
+                      {
+                        "tag": "i"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "nobr",
+                    "children": [
+                      {
+                        "text": "3"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b><nobr>1</nobr><nobr></nobr></b><nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr></body></html>",
+        "noQuirksBodyHtml": "<b><nobr>1</nobr><nobr></nobr></b><nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><b><nobr>1<table><nobr></b><i><nobr>2<nobr></i>3",
+      "errors": [
+        "(1,44): foster-parenting-start-tag",
+        "(1,48): foster-parenting-end-tag",
+        "(1,48): adoption-agency-1.3",
+        "(1,51): foster-parenting-start-tag",
+        "(1,57): foster-parenting-start-tag",
+        "(1,57): nobr-already-in-scope",
+        "(1,57): adoption-agency-1.2",
+        "(1,58): foster-parenting-character",
+        "(1,64): foster-parenting-start-tag",
+        "(1,64): nobr-already-in-scope",
+        "(1,68): foster-parenting-end-tag",
+        "(1,68): adoption-agency-1.2",
+        "(1,69): foster-parenting-character",
+        "(1,69): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "i": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "1"
+                          },
+                          {
+                            "tag": "nobr",
+                            "children": [
+                              {
+                                "tag": "i"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "tag": "nobr",
+                                "children": [
+                                  {
+                                    "text": "2"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "nobr"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "nobr",
+                            "children": [
+                              {
+                                "text": "3"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "table"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b><nobr>1<nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr><table></table></nobr></b></body></html>",
+        "noQuirksBodyHtml": "<b><nobr>1<nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr><table></table></nobr></b>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><b><nobr>1<table><tr><td><nobr></b><i><nobr>2<nobr></i>3",
+      "errors": [
+        "(1,56): unexpected-end-tag",
+        "(1,65): unexpected-start-tag-implies-end-tag",
+        "(1,65): adoption-agency-1.3",
+        "(1,72): unexpected-start-tag-implies-end-tag",
+        "(1,76): adoption-agency-1.3",
+        "(1,77): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "1"
+                          },
+                          {
+                            "tag": "table",
+                            "children": [
+                              {
+                                "tag": "tbody",
+                                "children": [
+                                  {
+                                    "tag": "tr",
+                                    "children": [
+                                      {
+                                        "tag": "td",
+                                        "children": [
+                                          {
+                                            "tag": "nobr",
+                                            "children": [
+                                              {
+                                                "tag": "i"
+                                              }
+                                            ]
+                                          },
+                                          {
+                                            "tag": "i",
+                                            "children": [
+                                              {
+                                                "tag": "nobr",
+                                                "children": [
+                                                  {
+                                                    "text": "2"
+                                                  }
+                                                ]
+                                              },
+                                              {
+                                                "tag": "nobr"
+                                              }
+                                            ]
+                                          },
+                                          {
+                                            "tag": "nobr",
+                                            "children": [
+                                              {
+                                                "text": "3"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b><nobr>1<table><tbody><tr><td><nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr></td></tr></tbody></table></nobr></b></body></html>",
+        "noQuirksBodyHtml": "<b><nobr>1<table><tbody><tr><td><nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr></td></tr></tbody></table></nobr></b>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><b><nobr>1<div><nobr></b><i><nobr>2<nobr></i>3",
+      "errors": [
+        "(1,42): unexpected-start-tag-implies-end-tag",
+        "(1,42): adoption-agency-1.3",
+        "(1,46): adoption-agency-1.3",
+        "(1,46): adoption-agency-1.3",
+        "(1,55): unexpected-start-tag-implies-end-tag",
+        "(1,55): adoption-agency-1.3",
+        "(1,62): unexpected-start-tag-implies-end-tag",
+        "(1,66): adoption-agency-1.3",
+        "(1,67): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "div": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "1"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "nobr"
+                          },
+                          {
+                            "tag": "nobr"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "tag": "i"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "tag": "nobr",
+                            "children": [
+                              {
+                                "text": "2"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "nobr"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "3"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b><nobr>1</nobr></b><div><b><nobr></nobr><nobr></nobr></b><nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr></div></body></html>",
+        "noQuirksBodyHtml": "<b><nobr>1</nobr></b><div><b><nobr></nobr><nobr></nobr></b><nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr></div>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><b><nobr>1<nobr></b><div><i><nobr>2<nobr></i>3",
+      "errors": [
+        "(1,37): unexpected-start-tag-implies-end-tag",
+        "(1,41): adoption-agency-1.3",
+        "(1,55): unexpected-start-tag-implies-end-tag",
+        "(1,55): adoption-agency-1.3",
+        "(1,62): unexpected-start-tag-implies-end-tag",
+        "(1,66): adoption-agency-1.3",
+        "(1,67): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "div": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "1"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "tag": "i"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "tag": "nobr",
+                            "children": [
+                              {
+                                "text": "2"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "nobr"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "3"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b><nobr>1</nobr><nobr></nobr></b><div><nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr></div></body></html>",
+        "noQuirksBodyHtml": "<b><nobr>1</nobr><nobr></nobr></b><div><nobr><i></i></nobr><i><nobr>2</nobr><nobr></nobr></i><nobr>3</nobr></div>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><b><nobr>1<nobr><ins></b><i><nobr>",
+      "errors": [
+        "(1,37): unexpected-start-tag-implies-end-tag",
+        "(1,46): adoption-agency-1.3",
+        "(1,55): unexpected-start-tag-implies-end-tag",
+        "(1,55): adoption-agency-1.3",
+        "(1,55): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "ins": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "1"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "tag": "ins"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "nobr",
+                    "children": [
+                      {
+                        "tag": "i"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b><nobr>1</nobr><nobr><ins></ins></nobr></b><nobr><i></i></nobr><i><nobr></nobr></i></body></html>",
+        "noQuirksBodyHtml": "<b><nobr>1</nobr><nobr><ins></ins></nobr></b><nobr><i></i></nobr><i><nobr></nobr></i>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><b><nobr>1<ins><nobr></b><i>2",
+      "errors": [
+        "(1,42): unexpected-start-tag-implies-end-tag",
+        "(1,42): adoption-agency-1.3",
+        "(1,46): adoption-agency-1.3",
+        "(1,50): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "ins": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "1"
+                          },
+                          {
+                            "tag": "ins"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "nobr",
+                    "children": [
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b><nobr>1<ins></ins></nobr><nobr></nobr></b><nobr><i>2</i></nobr></body></html>",
+        "noQuirksBodyHtml": "<b><nobr>1<ins></ins></nobr><nobr></nobr></b><nobr><i>2</i></nobr>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><b>1<nobr></b><i><nobr>2</i>",
+      "errors": [
+        "(1,35): adoption-agency-1.3",
+        "(1,44): unexpected-start-tag-implies-end-tag",
+        "(1,44): adoption-agency-1.3",
+        "(1,49): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "1"
+                      },
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "nobr",
+                    "children": [
+                      {
+                        "tag": "i"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "tag": "nobr",
+                        "children": [
+                          {
+                            "text": "2"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><b>1<nobr></nobr></b><nobr><i></i></nobr><i><nobr>2</nobr></i></body></html>",
+        "noQuirksBodyHtml": "<b>1<nobr></nobr></b><nobr><i></i></nobr><i><nobr>2</nobr></i>"
+      }
+    },
+    {
+      "data": "<p><code x</code></p>\n",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,11): invalid-character-in-attribute-name",
+        "(1,12): unexpected-character-after-solidus-in-tag",
+        "(1,21): unexpected-end-tag",
+        "(2,0): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "code": true
+          },
+          "attrWithFunnyChar": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "code",
+                        "attrs": [
+                          {
+                            "name": "code",
+                            "value": ""
+                          },
+                          {
+                            "name": "x<",
+                            "value": ""
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "code",
+                    "attrs": [
+                      {
+                        "name": "code",
+                        "value": ""
+                      },
+                      {
+                        "name": "x<",
+                        "value": ""
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "\n"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><code x<=\"\" code=\"\"></code></p><code x<=\"\" code=\"\">\n</code></body></html>",
+        "noQuirksBodyHtml": "<p><code x<=\"\" code=\"\"></code></p><code x<=\"\" code=\"\">\n</code>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><svg><foreignObject><p><i></p>a",
+      "errors": [
+        "(1,45): unexpected-end-tag",
+        "(1,46): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "p": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "tag": "i"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "a"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg><foreignObject><p><i></i></p><i>a</i></foreignObject></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><foreignObject><p><i></i></p><i>a</i></foreignObject></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><table><tr><td><svg><foreignObject><p><i></p>a",
+      "errors": [
+        "(1,60): unexpected-end-tag",
+        "(1,61): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "p": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "foreignObject",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "tag": "p",
+                                            "children": [
+                                              {
+                                                "tag": "i"
+                                              }
+                                            ]
+                                          },
+                                          {
+                                            "tag": "i",
+                                            "children": [
+                                              {
+                                                "text": "a"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><svg><foreignObject><p><i></i></p><i>a</i></foreignObject></svg></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><svg><foreignObject><p><i></i></p><i>a</i></foreignObject></svg></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><math><mtext><p><i></p>a",
+      "errors": [
+        "(1,38): unexpected-end-tag",
+        "(1,39): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mtext": true,
+            "p": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mtext",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "tag": "i"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "a"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mtext><p><i></i></p><i>a</i></mtext></math></body></html>",
+        "noQuirksBodyHtml": "<math><mtext><p><i></i></p><i>a</i></mtext></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><table><tr><td><math><mtext><p><i></p>a",
+      "errors": [
+        "(1,53): unexpected-end-tag",
+        "(1,54): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "math math": true,
+            "math mtext": true,
+            "p": true,
+            "i": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "math",
+                                    "ns": "http://www.w3.org/1998/Math/MathML",
+                                    "children": [
+                                      {
+                                        "tag": "mtext",
+                                        "ns": "http://www.w3.org/1998/Math/MathML",
+                                        "children": [
+                                          {
+                                            "tag": "p",
+                                            "children": [
+                                              {
+                                                "tag": "i"
+                                              }
+                                            ]
+                                          },
+                                          {
+                                            "tag": "i",
+                                            "children": [
+                                              {
+                                                "text": "a"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><math><mtext><p><i></i></p><i>a</i></mtext></math></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><math><mtext><p><i></i></p><i>a</i></mtext></math></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><div><!/div>a",
+      "errors": [
+        "(1,28): expected-dashes-or-doctype",
+        "(1,34): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          },
+          "doctype": true,
+          "comment": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "comment": "/div"
+                      },
+                      {
+                        "text": "a"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><div><!--/div-->a</div></body></html>",
+        "noQuirksBodyHtml": "<div><!--/div-->a</div>"
+      }
+    },
+    {
+      "data": "<button><p><button>",
+      "errors": [
+        "Line 1 Col 8 Unexpected start tag (button). Expected DOCTYPE.",
+        "Line 1 Col 19 Unexpected start tag (button) implies end tag (button).",
+        "Line 1 Col 19 Expected closing tag. Unexpected end of file."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "button": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "button",
+                    "children": [
+                      {
+                        "tag": "p"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "button"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><button><p></p></button><button></button></body></html>",
+        "noQuirksBodyHtml": "<button><p></p></button><button></button>"
+      }
+    }
+  ],
+  "tests3.dat": [
+    {
+      "data": "<head></head><style></style>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,20): unexpected-start-tag-out-of-my-head"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style></style></head><body></body></html>",
+        "noQuirksBodyHtml": "<style></style>"
+      }
+    },
+    {
+      "data": "<head></head><script></script>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,21): unexpected-start-tag-out-of-my-head"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script></script></head><body></body></html>",
+        "noQuirksBodyHtml": "<script></script>"
+      }
+    },
+    {
+      "data": "<head></head><!-- --><style></style><!-- --><script></script>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,28): unexpected-start-tag-out-of-my-head",
+        "(1,52): unexpected-start-tag-out-of-my-head"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "script": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style"
+                  },
+                  {
+                    "tag": "script"
+                  }
+                ]
+              },
+              {
+                "comment": " "
+              },
+              {
+                "comment": " "
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style></style><script></script></head><!-- --><!-- --><body></body></html>",
+        "noQuirksBodyHtml": "<!-- --><style></style><!-- --><script></script>"
+      }
+    },
+    {
+      "data": "<head></head><!-- -->x<style></style><!-- --><script></script>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "style": true,
+            "script": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "comment": " "
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  },
+                  {
+                    "tag": "style"
+                  },
+                  {
+                    "comment": " "
+                  },
+                  {
+                    "tag": "script"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><!-- --><body>x<style></style><!-- --><script></script></body></html>",
+        "noQuirksBodyHtml": "<!-- -->x<style></style><!-- --><script></script>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><pre>\n</pre></body></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre></pre></body></html>",
+        "noQuirksBodyHtml": "<pre></pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><pre>\nfoo</pre></body></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>foo</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>foo</pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><pre>\n\nfoo</pre></body></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true,
+          "extraNL": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "\nfoo",
+                        "extraNL": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>\n\nfoo</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>\n\nfoo</pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><pre>\nfoo\n</pre></body></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "foo\n"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>foo\n</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>foo\n</pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><pre>x</pre><span>\n</span></body></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true,
+            "span": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "x"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "span",
+                    "children": [
+                      {
+                        "text": "\n"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>x</pre><span>\n</span></body></html>",
+        "noQuirksBodyHtml": "<pre>x</pre><span>\n</span>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><pre>x\ny</pre></body></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "x\ny"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>x\ny</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>x\ny</pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><pre>x<div>\ny</pre></body></html>",
+      "errors": [
+        "(2,7): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true,
+            "div": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "x"
+                      },
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "text": "\ny"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>x<div>\ny</div></pre></body></html>",
+        "noQuirksBodyHtml": "<pre>x<div>\ny</div></pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><pre>&#x0a;&#x0a;A</pre>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "pre": true
+          },
+          "doctype": true,
+          "extraNL": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "pre",
+                    "children": [
+                      {
+                        "text": "\nA",
+                        "extraNL": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><pre>\n\nA</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>\n\nA</pre>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><HTML><META><HEAD></HEAD></HTML>",
+      "errors": [
+        "(1,33): two-heads-are-not-better-than-one"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "meta": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "meta"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><meta></head><body></body></html>",
+        "noQuirksBodyHtml": "<meta>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><HTML><HEAD><head></HEAD></HTML>",
+      "errors": [
+        "(1,33): two-heads-are-not-better-than-one"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<textarea>foo<span>bar</span><i>baz",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,35): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "foo<span>bar</span><i>baz",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><textarea>foo&lt;span&gt;bar&lt;/span&gt;&lt;i&gt;baz</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>foo&lt;span&gt;bar&lt;/span&gt;&lt;i&gt;baz</textarea>"
+      }
+    },
+    {
+      "data": "<title>foo<span>bar</em><i>baz",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,30): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "foo<span>bar</em><i>baz",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title>foo&lt;span&gt;bar&lt;/em&gt;&lt;i&gt;baz</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>foo&lt;span&gt;bar&lt;/em&gt;&lt;i&gt;baz</title>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><textarea>\n</textarea>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><textarea></textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea></textarea>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><textarea>\nfoo</textarea>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><textarea>foo</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>foo</textarea>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><textarea>\n\nfoo</textarea>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "doctype": true,
+          "extraNL": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": "\nfoo",
+                        "extraNL": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><textarea>\n\nfoo</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>\n\nfoo</textarea>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html><head></head><body><ul><li><div><p><li></ul></body></html>",
+      "errors": [
+        "(1,60): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ul": true,
+            "li": true,
+            "div": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ul",
+                    "children": [
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "tag": "p"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "li"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><ul><li><div><p></p></div></li><li></li></ul></body></html>",
+        "noQuirksBodyHtml": "<ul><li><div><p></p></div></li><li></li></ul>"
+      }
+    },
+    {
+      "data": "<!doctype html><nobr><nobr><nobr>",
+      "errors": [
+        "(1,27): unexpected-start-tag-implies-end-tag",
+        "(1,33): unexpected-start-tag-implies-end-tag",
+        "(1,33): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "nobr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "nobr"
+                  },
+                  {
+                    "tag": "nobr"
+                  },
+                  {
+                    "tag": "nobr"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><nobr></nobr><nobr></nobr><nobr></nobr></body></html>",
+        "noQuirksBodyHtml": "<nobr></nobr><nobr></nobr><nobr></nobr>"
+      }
+    },
+    {
+      "data": "<!doctype html><nobr><nobr></nobr><nobr>",
+      "errors": [
+        "(1,27): unexpected-start-tag-implies-end-tag",
+        "(1,40): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "nobr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "nobr"
+                  },
+                  {
+                    "tag": "nobr"
+                  },
+                  {
+                    "tag": "nobr"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><nobr></nobr><nobr></nobr><nobr></nobr></body></html>",
+        "noQuirksBodyHtml": "<nobr></nobr><nobr></nobr><nobr></nobr>"
+      }
+    },
+    {
+      "data": "<!doctype html><html><body><p><table></table></body></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p></p><table></table></body></html>",
+        "noQuirksBodyHtml": "<p></p><table></table>"
+      }
+    },
+    {
+      "data": "<p><table></table>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "table"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><table></table></p></body></html>",
+        "noQuirksBodyHtml": "<p></p><table></table>"
+      }
+    }
+  ],
+  "tests4.dat": [
+    {
+      "data": "direct div content",
+      "errors": [],
+      "fragment": {
+        "name": "div"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "direct div content"
+          }
+        ],
+        "html": "direct div content",
+        "noQuirksBodyHtml": "direct div content"
+      }
+    },
+    {
+      "data": "direct textarea content",
+      "errors": [],
+      "fragment": {
+        "name": "textarea"
+      },
+      "document": {
+        "props": {
+          "tags": {}
+        },
+        "tree": [
+          {
+            "text": "direct textarea content"
+          }
+        ],
+        "html": "direct textarea content",
+        "noQuirksBodyHtml": "direct textarea content"
+      }
+    },
+    {
+      "data": "textarea content with <em>pseudo</em> <foo>markup",
+      "errors": [],
+      "fragment": {
+        "name": "textarea"
+      },
+      "document": {
+        "props": {
+          "tags": {},
+          "escaped": true
+        },
+        "tree": [
+          {
+            "text": "textarea content with <em>pseudo</em> <foo>markup",
+            "escaped": true
+          }
+        ],
+        "html": "textarea content with &lt;em&gt;pseudo&lt;/em&gt; &lt;foo&gt;markup",
+        "noQuirksBodyHtml": "textarea content with <em>pseudo</em> <foo>markup</foo>"
+      }
+    },
+    {
+      "data": "this is &#x0043;DATA inside a <style> element",
+      "errors": [],
+      "fragment": {
+        "name": "style"
+      },
+      "document": {
+        "props": {
+          "tags": {},
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "text": "this is &#x0043;DATA inside a <style> element",
+            "no_escape": true
+          }
+        ],
+        "html": "this is &#x0043;DATA inside a <style> element",
+        "noQuirksBodyHtml": "this is CDATA inside a <style> element</style>"
+      }
+    },
+    {
+      "data": "</plaintext>",
+      "errors": [],
+      "fragment": {
+        "name": "plaintext"
+      },
+      "document": {
+        "props": {
+          "tags": {},
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "text": "</plaintext>",
+            "no_escape": true
+          }
+        ],
+        "html": "</plaintext>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "setting html's innerHTML",
+      "errors": [],
+      "fragment": {
+        "name": "html"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "head"
+          },
+          {
+            "tag": "body",
+            "children": [
+              {
+                "text": "setting html's innerHTML"
+              }
+            ]
+          }
+        ],
+        "html": "<head></head><body>setting html's innerHTML</body>",
+        "noQuirksBodyHtml": "setting html's innerHTML"
+      }
+    },
+    {
+      "data": "<title>setting head's innerHTML</title>",
+      "errors": [],
+      "fragment": {
+        "name": "head"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "title": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "title",
+            "children": [
+              {
+                "text": "setting head's innerHTML"
+              }
+            ]
+          }
+        ],
+        "html": "<title>setting head's innerHTML</title>",
+        "noQuirksBodyHtml": "<title>setting head's innerHTML</title>"
+      }
+    }
+  ],
+  "tests5.dat": [
+    {
+      "data": "<style> <!-- </style>x",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": " <!-- ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style> <!-- </style></head><body>x</body></html>",
+        "noQuirksBodyHtml": "<style> <!-- </style>x"
+      }
+    },
+    {
+      "data": "<style> <!-- </style> --> </style>x",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,34): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": " <!-- ",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": " "
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "--> x",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style> <!-- </style> </head><body>--&gt; x</body></html>",
+        "noQuirksBodyHtml": "<style> <!-- </style> --&gt; x"
+      }
+    },
+    {
+      "data": "<style> <!--> </style>x",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": " <!--> ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style> <!--> </style></head><body>x</body></html>",
+        "noQuirksBodyHtml": "<style> <!--> </style>x"
+      }
+    },
+    {
+      "data": "<style> <!---> </style>x",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": " <!---> ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style> <!---> </style></head><body>x</body></html>",
+        "noQuirksBodyHtml": "<style> <!---> </style>x"
+      }
+    },
+    {
+      "data": "<iframe> <!---> </iframe>x",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "iframe": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe",
+                    "children": [
+                      {
+                        "text": " <!---> ",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "x"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><iframe> <!---> </iframe>x</body></html>",
+        "noQuirksBodyHtml": "<iframe> <!---> </iframe>x"
+      }
+    },
+    {
+      "data": "<iframe> <!--- </iframe>->x</iframe> --> </iframe>x",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,36): unexpected-end-tag",
+        "(1,50): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "iframe": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "iframe",
+                    "children": [
+                      {
+                        "text": " <!--- ",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "->x --> x",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><iframe> <!--- </iframe>-&gt;x --&gt; x</body></html>",
+        "noQuirksBodyHtml": "<iframe> <!--- </iframe>-&gt;x --&gt; x"
+      }
+    },
+    {
+      "data": "<script> <!-- </script> --> </script>x",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,37): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "script": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": " <!-- ",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": " "
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "--> x",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><script> <!-- </script> </head><body>--&gt; x</body></html>",
+        "noQuirksBodyHtml": "<script> <!-- </script> --&gt; x"
+      }
+    },
+    {
+      "data": "<title> <!-- </title> --> </title>x",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,34): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": " <!-- ",
+                        "escaped": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": " "
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "--> x",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title> &lt;!-- </title> </head><body>--&gt; x</body></html>",
+        "noQuirksBodyHtml": "<title> &lt;!-- </title> --&gt; x"
+      }
+    },
+    {
+      "data": "<textarea> <!--- </textarea>->x</textarea> --> </textarea>x",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,42): unexpected-end-tag",
+        "(1,58): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "textarea": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "textarea",
+                    "children": [
+                      {
+                        "text": " <!--- ",
+                        "escaped": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "->x --> x",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><textarea> &lt;!--- </textarea>-&gt;x --&gt; x</body></html>",
+        "noQuirksBodyHtml": "<textarea> &lt;!--- </textarea>-&gt;x --&gt; x"
+      }
+    },
+    {
+      "data": "<style> <!</-- </style>x",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style",
+                    "children": [
+                      {
+                        "text": " <!</-- ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style> <!</-- </style></head><body>x</body></html>",
+        "noQuirksBodyHtml": "<style> <!</-- </style>x"
+      }
+    },
+    {
+      "data": "<p><xmp></xmp>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "xmp": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p"
+                  },
+                  {
+                    "tag": "xmp"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p></p><xmp></xmp></body></html>",
+        "noQuirksBodyHtml": "<p></p><xmp></xmp>"
+      }
+    },
+    {
+      "data": "<xmp> <!-- > --> </xmp>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "xmp": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "xmp",
+                    "children": [
+                      {
+                        "text": " <!-- > --> ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><xmp> <!-- > --> </xmp></body></html>",
+        "noQuirksBodyHtml": "<xmp> <!-- > --> </xmp>"
+      }
+    },
+    {
+      "data": "<title>&amp;</title>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "&",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title>&amp;</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>&amp;</title>"
+      }
+    },
+    {
+      "data": "<title><!--&amp;--></title>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<!--&-->",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title>&lt;!--&amp;--&gt;</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>&lt;!--&amp;--&gt;</title>"
+      }
+    },
+    {
+      "data": "<title><!--</title>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><title>&lt;!--</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>&lt;!--</title>"
+      }
+    },
+    {
+      "data": "<noscript><!--</noscript>--></noscript>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,39): unexpected-end-tag"
+      ],
+      "script": "on",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "no_escape": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "<!--",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "-->",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><!--</noscript></head><body>--&gt;</body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>--&gt;"
+      }
+    },
+    {
+      "data": "<noscript><!--</noscript>--></noscript>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "</noscript>"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><!--</noscript>--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>--&gt;"
+      }
+    }
+  ],
+  "tests6.dat": [
+    {
+      "data": "<!doctype html></head> <head>",
+      "errors": [
+        "(1,29): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "text": " "
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head> <body></body></html>",
+        "noQuirksBodyHtml": " "
+      }
+    },
+    {
+      "data": "<!doctype html><form><div></form><div>",
+      "errors": [
+        "(1,33): end-tag-too-early-ignored",
+        "(1,38): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true,
+            "div": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><form><div><div></div></div></form></body></html>",
+        "noQuirksBodyHtml": "<form><div><div></div></div></form>"
+      }
+    },
+    {
+      "data": "<!doctype html><title>&amp;</title>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "&",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><title>&amp;</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>&amp;</title>"
+      }
+    },
+    {
+      "data": "<!doctype html><title><!--&amp;--></title>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "doctype": true,
+          "escaped": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "<!--&-->",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><title>&lt;!--&amp;--&gt;</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>&lt;!--&amp;--&gt;</title>"
+      }
+    },
+    {
+      "data": "<!doctype>",
+      "errors": [
+        "(1,9): need-space-after-doctype",
+        "(1,10): expected-doctype-name-but-got-right-bracket",
+        "(1,10): unknown-doctype"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": ""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE ><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!---x",
+      "errors": [
+        "(1,6): eof-in-comment",
+        "(1,6): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": "-x"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!---x--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!---x-->"
+      }
+    },
+    {
+      "data": "<body>\n<div>",
+      "errors": [
+        "(1,6): unexpected-start-tag",
+        "(2,5): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "div"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "text": "\n"
+          },
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "\n<div></div>",
+        "noQuirksBodyHtml": "\n<div></div>"
+      }
+    },
+    {
+      "data": "<frameset></frameset>\nfoo",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(2,1): unexpected-char-after-frameset",
+        "(2,2): unexpected-char-after-frameset",
+        "(2,3): unexpected-char-after-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "text": "\n"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset>\n</html>",
+        "noQuirksBodyHtml": "\nfoo"
+      }
+    },
+    {
+      "data": "<frameset></frameset>\n<noframes>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(2,10): expected-named-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "noframes": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "text": "\n"
+              },
+              {
+                "tag": "noframes"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset>\n<noframes></noframes></html>",
+        "noQuirksBodyHtml": "\n<noframes></noframes>"
+      }
+    },
+    {
+      "data": "<frameset></frameset>\n<div>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(2,5): unexpected-start-tag-after-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "text": "\n"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset>\n</html>",
+        "noQuirksBodyHtml": "\n<div></div>"
+      }
+    },
+    {
+      "data": "<frameset></frameset>\n</html>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "text": "\n"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset>\n</html>",
+        "noQuirksBodyHtml": "\n"
+      }
+    },
+    {
+      "data": "<frameset></frameset>\n</div>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(2,6): unexpected-end-tag-after-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "text": "\n"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset>\n</html>",
+        "noQuirksBodyHtml": "\n"
+      }
+    },
+    {
+      "data": "<form><form>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,12): unexpected-start-tag",
+        "(1,12): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "form": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "form"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><form></form></body></html>",
+        "noQuirksBodyHtml": "<form></form>"
+      }
+    },
+    {
+      "data": "<button><button>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,16): unexpected-start-tag-implies-end-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "button": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "button"
+                  },
+                  {
+                    "tag": "button"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><button></button><button></button></body></html>",
+        "noQuirksBodyHtml": "<button></button><button></button>"
+      }
+    },
+    {
+      "data": "<table><tr><td></th>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,20): unexpected-end-tag",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><caption><td>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,20): unexpected-cell-in-table-body",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption"
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><caption></caption><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption></caption><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><caption><div>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><caption><div></div></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption><div></div></caption></table>"
+      }
+    },
+    {
+      "data": "</caption><div>",
+      "errors": [
+        "(1,10): XXX-undefined-error",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<table><caption><div></caption>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,31): expected-one-end-tag-but-got-another",
+        "(1,31): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><caption><div></div></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption><div></div></caption></table>"
+      }
+    },
+    {
+      "data": "<table><caption></table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><caption></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption></caption></table>"
+      }
+    },
+    {
+      "data": "</table><div>",
+      "errors": [
+        "(1,8): unexpected-end-tag",
+        "(1,13): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<table><caption></body></col></colgroup></html></tbody></td></tfoot></th></thead></tr>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,23): unexpected-end-tag",
+        "(1,29): unexpected-end-tag",
+        "(1,40): unexpected-end-tag",
+        "(1,47): unexpected-end-tag",
+        "(1,55): unexpected-end-tag",
+        "(1,60): unexpected-end-tag",
+        "(1,68): unexpected-end-tag",
+        "(1,73): unexpected-end-tag",
+        "(1,81): unexpected-end-tag",
+        "(1,86): unexpected-end-tag",
+        "(1,86): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><caption></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption></caption></table>"
+      }
+    },
+    {
+      "data": "<table><caption><div></div>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,27): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><caption><div></div></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption><div></div></caption></table>"
+      }
+    },
+    {
+      "data": "<table><tr><td></body></caption></col></colgroup></html>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,22): unexpected-end-tag",
+        "(1,32): unexpected-end-tag",
+        "(1,38): unexpected-end-tag",
+        "(1,49): unexpected-end-tag",
+        "(1,56): unexpected-end-tag",
+        "(1,56): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "</table></tbody></tfoot></thead></tr><div>",
+      "errors": [
+        "(1,8): unexpected-end-tag",
+        "(1,16): unexpected-end-tag",
+        "(1,24): unexpected-end-tag",
+        "(1,32): unexpected-end-tag",
+        "(1,37): unexpected-end-tag",
+        "(1,42): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<table><colgroup>foo",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,18): foster-parenting-character-in-table",
+        "(1,19): foster-parenting-character-in-table",
+        "(1,20): foster-parenting-character-in-table",
+        "(1,20): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "foo"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>foo<table><colgroup></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "foo<table><colgroup></colgroup></table>"
+      }
+    },
+    {
+      "data": "foo<col>",
+      "errors": [
+        "(1,1): unexpected-character-in-colgroup",
+        "(1,2): unexpected-character-in-colgroup",
+        "(1,3): unexpected-character-in-colgroup"
+      ],
+      "fragment": {
+        "name": "colgroup"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "col": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "col"
+          }
+        ],
+        "html": "<col>",
+        "noQuirksBodyHtml": "foo"
+      }
+    },
+    {
+      "data": "<table><colgroup></col>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,23): no-end-tag",
+        "(1,23): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "colgroup": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><colgroup></colgroup></table></body></html>",
+        "noQuirksBodyHtml": "<table><colgroup></colgroup></table>"
+      }
+    },
+    {
+      "data": "<frameset><div>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,15): unexpected-start-tag-in-frameset",
+        "(1,15): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "</frameset><frame>",
+      "errors": [
+        "(1,11): unexpected-frameset-in-frameset-innerhtml"
+      ],
+      "fragment": {
+        "name": "frameset"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "frame": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "frame"
+          }
+        ],
+        "html": "<frame>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<frameset></div>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag",
+        "(1,16): unexpected-end-tag-in-frameset",
+        "(1,16): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "</body><div>",
+      "errors": [
+        "(1,7): unexpected-close-tag",
+        "(1,12): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "body"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "div"
+          }
+        ],
+        "html": "<div></div>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<table><tr><div>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,16): unexpected-start-tag-implies-table-voodoo",
+        "(1,16): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div></div><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<div></div><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "</tr><td>",
+      "errors": [
+        "(1,5): unexpected-end-tag"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "</tbody></tfoot></thead><td>",
+      "errors": [
+        "(1,8): unexpected-end-tag",
+        "(1,16): unexpected-end-tag",
+        "(1,24): unexpected-end-tag"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<table><tr><div><td>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,16): foster-parenting-start-tag",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div></div><table><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<div></div><table><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<caption><col><colgroup><tbody><tfoot><thead><tr>",
+      "errors": [
+        "(1,9): unexpected-start-tag",
+        "(1,14): unexpected-start-tag",
+        "(1,24): unexpected-start-tag",
+        "(1,31): unexpected-start-tag",
+        "(1,38): unexpected-start-tag",
+        "(1,45): unexpected-start-tag"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "tr"
+          }
+        ],
+        "html": "<tr></tr>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<table><tbody></thead>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,22): unexpected-end-tag-in-table-body",
+        "(1,22): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody></tbody></table>"
+      }
+    },
+    {
+      "data": "</table><tr>",
+      "errors": [
+        "(1,8): unexpected-end-tag"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "tr"
+          }
+        ],
+        "html": "<tr></tr>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<table><tbody></body></caption></col></colgroup></html></td></th></tr>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,21): unexpected-end-tag-in-table-body",
+        "(1,31): unexpected-end-tag-in-table-body",
+        "(1,37): unexpected-end-tag-in-table-body",
+        "(1,48): unexpected-end-tag-in-table-body",
+        "(1,55): unexpected-end-tag-in-table-body",
+        "(1,60): unexpected-end-tag-in-table-body",
+        "(1,65): unexpected-end-tag-in-table-body",
+        "(1,70): unexpected-end-tag-in-table-body",
+        "(1,70): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><tbody></div>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,20): unexpected-end-tag-implies-table-voodoo",
+        "(1,20): end-tag-too-early",
+        "(1,20): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-start-tag-implies-end-tag",
+        "(1,14): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table></table><table></table></body></html>",
+        "noQuirksBodyHtml": "<table></table><table></table>"
+      }
+    },
+    {
+      "data": "<table></body></caption></col></colgroup></html></tbody></td></tfoot></th></thead></tr>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-end-tag",
+        "(1,24): unexpected-end-tag",
+        "(1,30): unexpected-end-tag",
+        "(1,41): unexpected-end-tag",
+        "(1,48): unexpected-end-tag",
+        "(1,56): unexpected-end-tag",
+        "(1,61): unexpected-end-tag",
+        "(1,69): unexpected-end-tag",
+        "(1,74): unexpected-end-tag",
+        "(1,82): unexpected-end-tag",
+        "(1,87): unexpected-end-tag",
+        "(1,87): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table></table></body></html>",
+        "noQuirksBodyHtml": "<table></table>"
+      }
+    },
+    {
+      "data": "</table><tr>",
+      "errors": [
+        "(1,8): unexpected-end-tag"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "tbody",
+            "children": [
+              {
+                "tag": "tr"
+              }
+            ]
+          }
+        ],
+        "html": "<tbody><tr></tr></tbody>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<body></body></html>",
+      "errors": [
+        "(1,20): unexpected-end-tag-after-body-innerhtml"
+      ],
+      "fragment": {
+        "name": "html"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "head"
+          },
+          {
+            "tag": "body"
+          }
+        ],
+        "html": "<head></head><body></body>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<html><frameset></frameset></html> ",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              },
+              {
+                "text": " "
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset> </html>",
+        "noQuirksBodyHtml": " "
+      }
+    },
+    {
+      "data": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"><html></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html \"-//W3C//DTD HTML 4.01//EN\" \"\""
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<param><frameset></frameset>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,17): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<param>"
+      }
+    },
+    {
+      "data": "<source><frameset></frameset>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,18): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<source>"
+      }
+    },
+    {
+      "data": "<track><frameset></frameset>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,17): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<track>"
+      }
+    },
+    {
+      "data": "</html><frameset></frameset>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-end-tag",
+        "(1,17): expected-eof-but-got-start-tag",
+        "(1,17): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "</body><frameset></frameset>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-end-tag",
+        "(1,17): unexpected-start-tag-after-body",
+        "(1,17): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": ""
+      }
+    }
+  ],
+  "tests7.dat": [
+    {
+      "data": "<!doctype html><body><title>X</title>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "title": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><title>X</title></body></html>",
+        "noQuirksBodyHtml": "<title>X</title>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><title>X</title></table>",
+      "errors": [
+        "(1,29): unexpected-start-tag-implies-table-voodoo"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "title": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><title>X</title><table></table></body></html>",
+        "noQuirksBodyHtml": "<title>X</title><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><head></head><title>X</title>",
+      "errors": [
+        "(1,35): unexpected-start-tag-out-of-my-head"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><title>X</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>X</title>"
+      }
+    },
+    {
+      "data": "<!doctype html></head><title>X</title>",
+      "errors": [
+        "(1,29): unexpected-start-tag-out-of-my-head"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "title": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "title",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head><title>X</title></head><body></body></html>",
+        "noQuirksBodyHtml": "<title>X</title>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><meta></table>",
+      "errors": [
+        "(1,28): unexpected-start-tag-implies-table-voodoo"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "meta": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "meta"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><meta><table></table></body></html>",
+        "noQuirksBodyHtml": "<meta><table></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table>X<tr><td><table> <meta></table></table>",
+      "errors": [
+        "unexpected text in table",
+        "(1,45): unexpected-start-tag-implies-table-voodoo"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "meta": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "meta"
+                                  },
+                                  {
+                                    "tag": "table",
+                                    "children": [
+                                      {
+                                        "text": " "
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>X<table><tbody><tr><td><meta><table> </table></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "X<table><tbody><tr><td><meta><table> </table></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><html> <head>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": " "
+      }
+    },
+    {
+      "data": "<!doctype html> <head>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": " "
+      }
+    },
+    {
+      "data": "<!doctype html><table><style> <tr>x </style> </table>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "style": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "style",
+                        "children": [
+                          {
+                            "text": " <tr>x ",
+                            "no_escape": true
+                          }
+                        ]
+                      },
+                      {
+                        "text": " "
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><style> <tr>x </style> </table></body></html>",
+        "noQuirksBodyHtml": "<table><style> <tr>x </style> </table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><TBODY><script> <tr>x </script> </table>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "script": true
+          },
+          "doctype": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "script",
+                            "children": [
+                              {
+                                "text": " <tr>x ",
+                                "no_escape": true
+                              }
+                            ]
+                          },
+                          {
+                            "text": " "
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><script> <tr>x </script> </tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><script> <tr>x </script> </tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><applet><p>X</p></applet>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "applet": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "applet",
+                        "children": [
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "text": "X"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><applet><p>X</p></applet></p></body></html>",
+        "noQuirksBodyHtml": "<p><applet><p>X</p></applet></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><p><object type=\"application/x-non-existant-plugin\"><p>X</p></object>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "object": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "object",
+                        "attrs": [
+                          {
+                            "name": "type",
+                            "value": "application/x-non-existant-plugin"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "text": "X"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><object type=\"application/x-non-existant-plugin\"><p>X</p></object></p></body></html>",
+        "noQuirksBodyHtml": "<p><object type=\"application/x-non-existant-plugin\"><p>X</p></object></p>"
+      }
+    },
+    {
+      "data": "<!doctype html><listing>\nX</listing>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "listing": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "listing",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><listing>X</listing></body></html>",
+        "noQuirksBodyHtml": "<listing>X</listing>"
+      }
+    },
+    {
+      "data": "<!doctype html><select><input>X",
+      "errors": [
+        "(1,30): unexpected-input-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  },
+                  {
+                    "tag": "input"
+                  },
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select><input>X</body></html>",
+        "noQuirksBodyHtml": "<select></select><input>X"
+      }
+    },
+    {
+      "data": "<!doctype html><select><select>X",
+      "errors": [
+        "(1,31): unexpected-select-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  },
+                  {
+                    "text": "X"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select>X</body></html>",
+        "noQuirksBodyHtml": "<select></select>X"
+      }
+    },
+    {
+      "data": "<!doctype html><table><input type=hidDEN></table>",
+      "errors": [
+        "(1,41): unexpected-hidden-input-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "input",
+                        "attrs": [
+                          {
+                            "name": "type",
+                            "value": "hidDEN"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><input type=\"hidDEN\"></table></body></html>",
+        "noQuirksBodyHtml": "<table><input type=\"hidDEN\"></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table>X<input type=hidDEN></table>",
+      "errors": [
+        "(1,23): foster-parenting-character",
+        "(1,42): unexpected-hidden-input-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "X"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "input",
+                        "attrs": [
+                          {
+                            "name": "type",
+                            "value": "hidDEN"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>X<table><input type=\"hidDEN\"></table></body></html>",
+        "noQuirksBodyHtml": "X<table><input type=\"hidDEN\"></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table>  <input type=hidDEN></table>",
+      "errors": [
+        "(1,43): unexpected-hidden-input-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "text": "  "
+                      },
+                      {
+                        "tag": "input",
+                        "attrs": [
+                          {
+                            "name": "type",
+                            "value": "hidDEN"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table>  <input type=\"hidDEN\"></table></body></html>",
+        "noQuirksBodyHtml": "<table>  <input type=\"hidDEN\"></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table>  <input type='hidDEN'></table>",
+      "errors": [
+        "(1,45): unexpected-hidden-input-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "text": "  "
+                      },
+                      {
+                        "tag": "input",
+                        "attrs": [
+                          {
+                            "name": "type",
+                            "value": "hidDEN"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table>  <input type=\"hidDEN\"></table></body></html>",
+        "noQuirksBodyHtml": "<table>  <input type=\"hidDEN\"></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><input type=\" hidden\"><input type=hidDEN></table>",
+      "errors": [
+        "(1,44): unexpected-start-tag-implies-table-voodoo",
+        "(1,63): unexpected-hidden-input-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "input": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "input",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": " hidden"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "input",
+                        "attrs": [
+                          {
+                            "name": "type",
+                            "value": "hidDEN"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><input type=\" hidden\"><table><input type=\"hidDEN\"></table></body></html>",
+        "noQuirksBodyHtml": "<input type=\" hidden\"><table><input type=\"hidDEN\"></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><table><select>X<tr>",
+      "errors": [
+        "(1,30): unexpected-start-tag-implies-table-voodoo",
+        "(1,35): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,35): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select>X</select><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<select>X</select><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!doctype html><select>X</select>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "text": "X"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select>X</select></body></html>",
+        "noQuirksBodyHtml": "<select>X</select>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE hTmL><html></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE HTML><html></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<body>X</body></body>",
+      "errors": [
+        "(1,21): unexpected-end-tag-after-body"
+      ],
+      "fragment": {
+        "name": "html"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "head"
+          },
+          {
+            "tag": "body",
+            "children": [
+              {
+                "text": "X"
+              }
+            ]
+          }
+        ],
+        "html": "<head></head><body>X</body>",
+        "noQuirksBodyHtml": "X"
+      }
+    },
+    {
+      "data": "<div><p>a</x> b",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,13): unexpected-end-tag",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "a b"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><p>a b</p></div></body></html>",
+        "noQuirksBodyHtml": "<div><p>a b</p></div>"
+      }
+    },
+    {
+      "data": "<table><tr><td><code></code> </table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "code": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "code"
+                                  },
+                                  {
+                                    "text": " "
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td><code></code> </td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><code></code> </td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><b><tr><td>aaa</td></tr>bbb</table>ccc",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,10): foster-parenting-start-tag",
+        "(1,32): foster-parenting-character",
+        "(1,33): foster-parenting-character",
+        "(1,34): foster-parenting-character",
+        "(1,45): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "bbb"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "aaa"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "ccc"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b></b><b>bbb</b><table><tbody><tr><td>aaa</td></tr></tbody></table><b>ccc</b></body></html>",
+        "noQuirksBodyHtml": "<b></b><b>bbb</b><table><tbody><tr><td>aaa</td></tr></tbody></table><b>ccc</b>"
+      }
+    },
+    {
+      "data": "A<table><tr> B</tr> B</table>",
+      "errors": [
+        "(1,1): expected-doctype-but-got-chars",
+        "(1,13): foster-parenting-character",
+        "(1,14): foster-parenting-character",
+        "(1,20): foster-parenting-character",
+        "(1,21): foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "A B B"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>A B B<table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "A B B<table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "A<table><tr> B</tr> </em>C</table>",
+      "errors": [
+        "(1,1): expected-doctype-but-got-chars",
+        "(1,13): foster-parenting-character",
+        "(1,14): foster-parenting-character",
+        "(1,20): foster-parenting-character",
+        "(1,25): unexpected-end-tag",
+        "(1,26): foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "A BC"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          },
+                          {
+                            "text": " "
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>A BC<table><tbody><tr></tr> </tbody></table></body></html>",
+        "noQuirksBodyHtml": "A BC<table><tbody><tr></tr> </tbody></table>"
+      }
+    },
+    {
+      "data": "<select><keygen>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,16): unexpected-input-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "keygen": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  },
+                  {
+                    "tag": "keygen"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select></select><keygen></body></html>",
+        "noQuirksBodyHtml": "<select></select><keygen>"
+      }
+    }
+  ],
+  "tests8.dat": [
+    {
+      "data": "<div>\n<div></div>\n</span>x",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(3,7): unexpected-end-tag",
+        "(3,8): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "\n"
+                      },
+                      {
+                        "tag": "div"
+                      },
+                      {
+                        "text": "\nx"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>\n<div></div>\nx</div></body></html>",
+        "noQuirksBodyHtml": "<div>\n<div></div>\nx</div>"
+      }
+    },
+    {
+      "data": "<div>x<div></div>\n</span>x",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(2,7): unexpected-end-tag",
+        "(2,8): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "x"
+                      },
+                      {
+                        "tag": "div"
+                      },
+                      {
+                        "text": "\nx"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>x<div></div>\nx</div></body></html>",
+        "noQuirksBodyHtml": "<div>x<div></div>\nx</div>"
+      }
+    },
+    {
+      "data": "<div>x<div></div>x</span>x",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,25): unexpected-end-tag",
+        "(1,26): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "x"
+                      },
+                      {
+                        "tag": "div"
+                      },
+                      {
+                        "text": "xx"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>x<div></div>xx</div></body></html>",
+        "noQuirksBodyHtml": "<div>x<div></div>xx</div>"
+      }
+    },
+    {
+      "data": "<div>x<div></div>y</span>z",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,25): unexpected-end-tag",
+        "(1,26): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "x"
+                      },
+                      {
+                        "tag": "div"
+                      },
+                      {
+                        "text": "yz"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>x<div></div>yz</div></body></html>",
+        "noQuirksBodyHtml": "<div>x<div></div>yz</div>"
+      }
+    },
+    {
+      "data": "<table><div>x<div></div>x</span>x",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,12): foster-parenting-start-tag",
+        "(1,13): foster-parenting-character",
+        "(1,18): foster-parenting-start-tag",
+        "(1,24): foster-parenting-end-tag",
+        "(1,25): foster-parenting-start-tag",
+        "(1,32): foster-parenting-end-tag",
+        "(1,32): unexpected-end-tag",
+        "(1,33): foster-parenting-character",
+        "(1,33): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "x"
+                      },
+                      {
+                        "tag": "div"
+                      },
+                      {
+                        "text": "xx"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>x<div></div>xx</div><table></table></body></html>",
+        "noQuirksBodyHtml": "<div>x<div></div>xx</div><table></table>"
+      }
+    },
+    {
+      "data": "x<table>x",
+      "errors": [
+        "(1,1): expected-doctype-but-got-chars",
+        "(1,9): foster-parenting-character",
+        "(1,9): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "xx"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>xx<table></table></body></html>",
+        "noQuirksBodyHtml": "xx<table></table>"
+      }
+    },
+    {
+      "data": "x<table><table>x",
+      "errors": [
+        "(1,1): expected-doctype-but-got-chars",
+        "(1,15): unexpected-start-tag-implies-end-tag",
+        "(1,16): foster-parenting-character",
+        "(1,16): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  },
+                  {
+                    "tag": "table"
+                  },
+                  {
+                    "text": "x"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>x<table></table>x<table></table></body></html>",
+        "noQuirksBodyHtml": "x<table></table>x<table></table>"
+      }
+    },
+    {
+      "data": "<b>a<div></div><div></b>y",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,24): adoption-agency-1.3",
+        "(1,25): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "a"
+                      },
+                      {
+                        "tag": "div"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b"
+                      },
+                      {
+                        "text": "y"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b>a<div></div></b><div><b></b>y</div></body></html>",
+        "noQuirksBodyHtml": "<b>a<div></div></b><div><b></b>y</div>"
+      }
+    },
+    {
+      "data": "<a><div><p></a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,15): adoption-agency-1.3",
+        "(1,15): adoption-agency-1.3",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "div": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a"
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "a"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "tag": "a"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a></a><div><a></a><p><a></a></p></div></body></html>",
+        "noQuirksBodyHtml": "<a></a><div><a></a><p><a></a></p></div>"
+      }
+    }
+  ],
+  "tests9.dat": [
+    {
+      "data": "<!DOCTYPE html><math></math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math></math></body></html>",
+        "noQuirksBodyHtml": "<math></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><math></math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math></math></body></html>",
+        "noQuirksBodyHtml": "<math></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><math><mi>",
+      "errors": [
+        "(1,25) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><mi></mi></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><math><annotation-xml><svg><u>",
+      "errors": [
+        "(1,45) unexpected-html-element-in-foreign-content",
+        "(1,45) expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "svg svg": true,
+            "u": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "u"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><annotation-xml><svg></svg></annotation-xml></math><u></u></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml><svg><u></u></svg></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><select><math></math></select>",
+      "errors": [
+        "(1,35) unexpected-start-tag-in-select",
+        "(1,42) unexpected-end-tag-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><select><option><math></math></option></select>",
+      "errors": [
+        "(1,43) unexpected-start-tag-in-select",
+        "(1,50) unexpected-end-tag-in-select"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select><option></option></select></body></html>",
+        "noQuirksBodyHtml": "<select><option></option></select>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><math></math></table>",
+      "errors": [
+        "(1,34) unexpected-start-tag-implies-table-voodoo"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math></math><table></table></body></html>",
+        "noQuirksBodyHtml": "<math></math><table></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><math><mi>foo</mi></math></table>",
+      "errors": [
+        "(1,34) foster-parenting-start-token",
+        "(1,39) foster-parenting-character",
+        "(1,40) foster-parenting-character",
+        "(1,41) foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi>foo</mi></math><table></table></body></html>",
+        "noQuirksBodyHtml": "<math><mi>foo</mi></math><table></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><math><mi>foo</mi><mi>bar</mi></math></table>",
+      "errors": [
+        "(1,34) foster-parenting-start-tag",
+        "(1,39) foster-parenting-character",
+        "(1,40) foster-parenting-character",
+        "(1,41) foster-parenting-character",
+        "(1,51) foster-parenting-character",
+        "(1,52) foster-parenting-character",
+        "(1,53) foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "table": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi>foo</mi><mi>bar</mi></math><table></table></body></html>",
+        "noQuirksBodyHtml": "<math><mi>foo</mi><mi>bar</mi></math><table></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tbody><math><mi>foo</mi><mi>bar</mi></math></tbody></table>",
+      "errors": [
+        "(1,41) foster-parenting-start-tag",
+        "(1,46) foster-parenting-character",
+        "(1,47) foster-parenting-character",
+        "(1,48) foster-parenting-character",
+        "(1,58) foster-parenting-character",
+        "(1,59) foster-parenting-character",
+        "(1,60) foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "table": true,
+            "tbody": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi>foo</mi><mi>bar</mi></math><table><tbody></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<math><mi>foo</mi><mi>bar</mi></math><table><tbody></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tbody><tr><math><mi>foo</mi><mi>bar</mi></math></tr></tbody></table>",
+      "errors": [
+        "(1,45) foster-parenting-start-tag",
+        "(1,50) foster-parenting-character",
+        "(1,51) foster-parenting-character",
+        "(1,52) foster-parenting-character",
+        "(1,62) foster-parenting-character",
+        "(1,63) foster-parenting-character",
+        "(1,64) foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi>foo</mi><mi>bar</mi></math><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<math><mi>foo</mi><mi>bar</mi></math><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math></td></tr></tbody></table>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "math math": true,
+            "math mi": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "math",
+                                    "ns": "http://www.w3.org/1998/Math/MathML",
+                                    "children": [
+                                      {
+                                        "tag": "mi",
+                                        "ns": "http://www.w3.org/1998/Math/MathML",
+                                        "children": [
+                                          {
+                                            "text": "foo"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "mi",
+                                        "ns": "http://www.w3.org/1998/Math/MathML",
+                                        "children": [
+                                          {
+                                            "text": "bar"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math><p>baz</td></tr></tbody></table>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "math math": true,
+            "math mi": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "math",
+                                    "ns": "http://www.w3.org/1998/Math/MathML",
+                                    "children": [
+                                      {
+                                        "tag": "mi",
+                                        "ns": "http://www.w3.org/1998/Math/MathML",
+                                        "children": [
+                                          {
+                                            "text": "foo"
+                                          }
+                                        ]
+                                      },
+                                      {
+                                        "tag": "mi",
+                                        "ns": "http://www.w3.org/1998/Math/MathML",
+                                        "children": [
+                                          {
+                                            "text": "bar"
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  },
+                                  {
+                                    "tag": "p",
+                                    "children": [
+                                      {
+                                        "text": "baz"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math><p>baz</p></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math><p>baz</p></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi></math><p>baz</caption></table>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "math math": true,
+            "math mi": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "math",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "mi",
+                                "ns": "http://www.w3.org/1998/Math/MathML",
+                                "children": [
+                                  {
+                                    "text": "foo"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "mi",
+                                "ns": "http://www.w3.org/1998/Math/MathML",
+                                "children": [
+                                  {
+                                    "text": "bar"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "text": "baz"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><math><mi>foo</mi><mi>bar</mi></math><p>baz</p></caption></table></body></html>",
+        "noQuirksBodyHtml": "<table><caption><math><mi>foo</mi><mi>bar</mi></math><p>baz</p></caption></table>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux",
+      "errors": [
+        "(1,70) unexpected-html-element-in-foreign-content"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "math math": true,
+            "math mi": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "math",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "mi",
+                                "ns": "http://www.w3.org/1998/Math/MathML",
+                                "children": [
+                                  {
+                                    "text": "foo"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "mi",
+                                "ns": "http://www.w3.org/1998/Math/MathML",
+                                "children": [
+                                  {
+                                    "text": "bar"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "p",
+                            "children": [
+                              {
+                                "text": "baz"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><math><mi>foo</mi><mi>bar</mi></math><p>baz</p></caption></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<table><caption><math><mi>foo</mi><mi>bar</mi><p>baz</p></math></caption></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi>baz</table><p>quux",
+      "errors": [
+        "(1,78) unexpected-end-tag",
+        "(1,78) expected-one-end-tag-but-got-another"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "caption": true,
+            "math math": true,
+            "math mi": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "caption",
+                        "children": [
+                          {
+                            "tag": "math",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "mi",
+                                "ns": "http://www.w3.org/1998/Math/MathML",
+                                "children": [
+                                  {
+                                    "text": "foo"
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "mi",
+                                "ns": "http://www.w3.org/1998/Math/MathML",
+                                "children": [
+                                  {
+                                    "text": "bar"
+                                  }
+                                ]
+                              },
+                              {
+                                "text": "baz"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><caption><math><mi>foo</mi><mi>bar</mi>baz</math></caption></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<table><caption><math><mi>foo</mi><mi>bar</mi>baz</math></caption></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><colgroup><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux",
+      "errors": [
+        "(1,44) foster-parenting-start-tag",
+        "(1,49) foster-parenting-character",
+        "(1,50) foster-parenting-character",
+        "(1,51) foster-parenting-character",
+        "(1,61) foster-parenting-character",
+        "(1,62) foster-parenting-character",
+        "(1,63) foster-parenting-character",
+        "(1,71) unexpected-html-element-in-foreign-content",
+        "(1,71) foster-parenting-start-tag",
+        "(1,63) foster-parenting-character",
+        "(1,63) foster-parenting-character",
+        "(1,63) foster-parenting-character"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "p": true,
+            "table": true,
+            "colgroup": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "baz"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "colgroup"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi>foo</mi><mi>bar</mi></math><p>baz</p><table><colgroup></colgroup></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<math><mi>foo</mi><mi>bar</mi><p>baz</p></math><table><colgroup></colgroup></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><tr><td><select><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux",
+      "errors": [
+        "(1,50) unexpected-start-tag-in-select",
+        "(1,54) unexpected-start-tag-in-select",
+        "(1,62) unexpected-end-tag-in-select",
+        "(1,66) unexpected-start-tag-in-select",
+        "(1,74) unexpected-end-tag-in-select",
+        "(1,77) unexpected-start-tag-in-select",
+        "(1,88) unexpected-table-element-end-tag-in-select-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "select": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "select",
+                                    "children": [
+                                      {
+                                        "text": "foobarbaz"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><table><tbody><tr><td><select>foobarbaz</select></td></tr></tbody></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><select>foobarbaz</select></td></tr></tbody></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><table><select><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux",
+      "errors": [
+        "(1,36) unexpected-start-tag-implies-table-voodoo",
+        "(1,42) unexpected-start-tag-in-select",
+        "(1,46) unexpected-start-tag-in-select",
+        "(1,54) unexpected-end-tag-in-select",
+        "(1,58) unexpected-start-tag-in-select",
+        "(1,66) unexpected-end-tag-in-select",
+        "(1,69) unexpected-start-tag-in-select",
+        "(1,80) unexpected-table-element-end-tag-in-select-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "table": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "text": "foobarbaz"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "quux"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select>foobarbaz</select><table></table><p>quux</p></body></html>",
+        "noQuirksBodyHtml": "<select>foobarbaz</select><table></table><p>quux</p>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body></body></html><math><mi>foo</mi><mi>bar</mi><p>baz",
+      "errors": [
+        "(1,41) expected-eof-but-got-start-tag",
+        "(1,68) unexpected-html-element-in-foreign-content"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "baz"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi>foo</mi><mi>bar</mi></math><p>baz</p></body></html>",
+        "noQuirksBodyHtml": "<math><mi>foo</mi><mi>bar</mi><p>baz</p></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body></body><math><mi>foo</mi><mi>bar</mi><p>baz",
+      "errors": [
+        "(1,34) unexpected-start-tag-after-body",
+        "(1,61) unexpected-html-element-in-foreign-content"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "text": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "baz"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math><mi>foo</mi><mi>bar</mi></math><p>baz</p></body></html>",
+        "noQuirksBodyHtml": "<math><mi>foo</mi><mi>bar</mi><p>baz</p></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><frameset><math><mi></mi><mi></mi><p><span>",
+      "errors": [
+        "(1,31) unexpected-start-tag-in-frameset",
+        "(1,35) unexpected-start-tag-in-frameset",
+        "(1,40) unexpected-end-tag-in-frameset",
+        "(1,44) unexpected-start-tag-in-frameset",
+        "(1,49) unexpected-end-tag-in-frameset",
+        "(1,52) unexpected-start-tag-in-frameset",
+        "(1,58) unexpected-start-tag-in-frameset",
+        "(1,58) eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<math><mi></mi><mi></mi><p><span></span></p></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><frameset></frameset><math><mi></mi><mi></mi><p><span>",
+      "errors": [
+        "(1,42) unexpected-start-tag-after-frameset",
+        "(1,46) unexpected-start-tag-after-frameset",
+        "(1,51) unexpected-end-tag-after-frameset",
+        "(1,55) unexpected-start-tag-after-frameset",
+        "(1,60) unexpected-end-tag-after-frameset",
+        "(1,63) unexpected-start-tag-after-frameset",
+        "(1,69) unexpected-start-tag-after-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<math><mi></mi><mi></mi><p><span></span></p></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body xlink:href=foo><math xlink:href=foo></math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "xlink:href",
+                    "value": "foo"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "attrs": [
+                      {
+                        "name": "href",
+                        "ns": "http://www.w3.org/1999/xlink",
+                        "value": "foo"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body xlink:href=\"foo\"><math xlink:href=\"foo\"></math></body></html>",
+        "noQuirksBodyHtml": "<math xlink:href=\"foo\"></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo></mi></math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "xlink:href",
+                    "value": "foo"
+                  },
+                  {
+                    "name": "xml:lang",
+                    "value": "en"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "ns": "http://www.w3.org/1999/xlink",
+                            "value": "foo"
+                          },
+                          {
+                            "name": "lang",
+                            "ns": "http://www.w3.org/XML/1998/namespace",
+                            "value": "en"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body xlink:href=\"foo\" xml:lang=\"en\"><math><mi xml:lang=\"en\" xlink:href=\"foo\"></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><mi xml:lang=\"en\" xlink:href=\"foo\"></mi></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo /></math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "xlink:href",
+                    "value": "foo"
+                  },
+                  {
+                    "name": "xml:lang",
+                    "value": "en"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "ns": "http://www.w3.org/1999/xlink",
+                            "value": "foo"
+                          },
+                          {
+                            "name": "lang",
+                            "ns": "http://www.w3.org/XML/1998/namespace",
+                            "value": "en"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body xlink:href=\"foo\" xml:lang=\"en\"><math><mi xml:lang=\"en\" xlink:href=\"foo\"></mi></math></body></html>",
+        "noQuirksBodyHtml": "<math><mi xml:lang=\"en\" xlink:href=\"foo\"></mi></math>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo />bar</math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mi": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "xlink:href",
+                    "value": "foo"
+                  },
+                  {
+                    "name": "xml:lang",
+                    "value": "en"
+                  }
+                ],
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mi",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "href",
+                            "ns": "http://www.w3.org/1999/xlink",
+                            "value": "foo"
+                          },
+                          {
+                            "name": "lang",
+                            "ns": "http://www.w3.org/XML/1998/namespace",
+                            "value": "en"
+                          }
+                        ]
+                      },
+                      {
+                        "text": "bar"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body xlink:href=\"foo\" xml:lang=\"en\"><math><mi xml:lang=\"en\" xlink:href=\"foo\"></mi>bar</math></body></html>",
+        "noQuirksBodyHtml": "<math><mi xml:lang=\"en\" xlink:href=\"foo\"></mi>bar</math>"
+      }
+    }
+  ],
+  "tests_innerHTML_1.dat": [
+    {
+      "data": "<body><span>",
+      "errors": [
+        "(1,6): unexpected-start-tag",
+        "(1,12): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "body"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<span><body>",
+      "errors": [
+        "(1,12): unexpected-start-tag",
+        "(1,12): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "body"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<span><body>",
+      "errors": [
+        "(1,12): unexpected-start-tag",
+        "(1,12): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "div"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<body><span>",
+      "errors": [
+        "(1,12): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "html"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "head": true,
+            "body": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "head"
+          },
+          {
+            "tag": "body",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<head></head><body><span></span></body>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<frameset><span>",
+      "errors": [
+        "(1,10): unexpected-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "body"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<span><frameset>",
+      "errors": [
+        "(1,16): unexpected-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "body"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<span><frameset>",
+      "errors": [
+        "(1,16): unexpected-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "div"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<frameset><span>",
+      "errors": [
+        "(1,16): unexpected-start-tag-in-frameset",
+        "(1,16): eof-in-frameset"
+      ],
+      "fragment": {
+        "name": "html"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "head": true,
+            "frameset": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "head"
+          },
+          {
+            "tag": "frameset"
+          }
+        ],
+        "html": "<head></head><frameset></frameset>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<table><tr>",
+      "errors": [
+        "(1,7): unexpected-start-tag"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "tbody",
+            "children": [
+              {
+                "tag": "tr"
+              }
+            ]
+          }
+        ],
+        "html": "<tbody><tr></tr></tbody>",
+        "noQuirksBodyHtml": "<table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "</table><tr>",
+      "errors": [
+        "(1,8): unexpected-end-tag"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "tbody",
+            "children": [
+              {
+                "tag": "tr"
+              }
+            ]
+          }
+        ],
+        "html": "<tbody><tr></tr></tbody>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<a>",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo",
+        "(1,3): eof-in-table"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a>",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo",
+        "(1,3): eof-in-table"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><caption>a",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo",
+        "(1,13): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "caption": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "caption",
+            "children": [
+              {
+                "text": "a"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><caption>a</caption>",
+        "noQuirksBodyHtml": "<a>a</a>"
+      }
+    },
+    {
+      "data": "<a><colgroup><col>",
+      "errors": [
+        "(1,3): foster-parenting-start-token",
+        "(1,18): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "colgroup": true,
+            "col": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "colgroup",
+            "children": [
+              {
+                "tag": "col"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><colgroup><col></colgroup>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><tbody><tr>",
+      "errors": [
+        "(1,3): foster-parenting-start-tag"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tbody",
+            "children": [
+              {
+                "tag": "tr"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><tbody><tr></tr></tbody>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><tfoot><tr>",
+      "errors": [
+        "(1,3): foster-parenting-start-tag"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tfoot": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tfoot",
+            "children": [
+              {
+                "tag": "tr"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><tfoot><tr></tr></tfoot>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><thead><tr>",
+      "errors": [
+        "(1,3): foster-parenting-start-tag"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "thead": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "thead",
+            "children": [
+              {
+                "tag": "tr"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><thead><tr></tr></thead>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><tr>",
+      "errors": [
+        "(1,3): foster-parenting-start-tag"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tbody",
+            "children": [
+              {
+                "tag": "tr"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><tbody><tr></tr></tbody>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><th>",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo",
+        "(1,7): unexpected-cell-in-table-body"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tbody": true,
+            "tr": true,
+            "th": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tbody",
+            "children": [
+              {
+                "tag": "tr",
+                "children": [
+                  {
+                    "tag": "th"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><tbody><tr><th></th></tr></tbody>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><td>",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo",
+        "(1,7): unexpected-cell-in-table-body"
+      ],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tbody",
+            "children": [
+              {
+                "tag": "tr",
+                "children": [
+                  {
+                    "tag": "td"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><tbody><tr><td></td></tr></tbody>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<table></table><tbody>",
+      "errors": [
+        "(1,22): unexpected-start-tag"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "table"
+          }
+        ],
+        "html": "<table></table>",
+        "noQuirksBodyHtml": "<table></table>"
+      }
+    },
+    {
+      "data": "</table><span>",
+      "errors": [
+        "(1,8): unexpected-end-tag",
+        "(1,14): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<span></table>",
+      "errors": [
+        "(1,14): unexpected-end-tag",
+        "(1,14): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "</caption><span>",
+      "errors": [
+        "(1,10): XXX-undefined-error",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span"
+          }
+        ],
+        "html": "<span></span>",
+        "noQuirksBodyHtml": "<span></span>"
+      }
+    },
+    {
+      "data": "<span></caption><span>",
+      "errors": [
+        "(1,16): XXX-undefined-error",
+        "(1,22): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><caption><span>",
+      "errors": [
+        "(1,15): unexpected-start-tag",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><col><span>",
+      "errors": [
+        "(1,11): unexpected-start-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><colgroup><span>",
+      "errors": [
+        "(1,16): unexpected-start-tag",
+        "(1,22): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><html><span>",
+      "errors": [
+        "(1,12): non-html-root",
+        "(1,18): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><tbody><span>",
+      "errors": [
+        "(1,13): unexpected-start-tag",
+        "(1,19): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><td><span>",
+      "errors": [
+        "(1,10): unexpected-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><tfoot><span>",
+      "errors": [
+        "(1,13): unexpected-start-tag",
+        "(1,19): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><thead><span>",
+      "errors": [
+        "(1,13): unexpected-start-tag",
+        "(1,19): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><th><span>",
+      "errors": [
+        "(1,10): unexpected-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span><tr><span>",
+      "errors": [
+        "(1,10): unexpected-start-tag",
+        "(1,16): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "<span></table><span>",
+      "errors": [
+        "(1,14): unexpected-end-tag",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "caption"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "span",
+            "children": [
+              {
+                "tag": "span"
+              }
+            ]
+          }
+        ],
+        "html": "<span><span></span></span>",
+        "noQuirksBodyHtml": "<span><span></span></span>"
+      }
+    },
+    {
+      "data": "</colgroup><col>",
+      "errors": [
+        "(1,11): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "colgroup"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "col": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "col"
+          }
+        ],
+        "html": "<col>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<a><col>",
+      "errors": [
+        "(1,3): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "colgroup"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "col": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "col"
+          }
+        ],
+        "html": "<col>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<caption><a>",
+      "errors": [
+        "(1,9): XXX-undefined-error",
+        "(1,12): unexpected-start-tag-implies-table-voodoo",
+        "(1,12): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<col><a>",
+      "errors": [
+        "(1,5): XXX-undefined-error",
+        "(1,8): unexpected-start-tag-implies-table-voodoo",
+        "(1,8): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<colgroup><a>",
+      "errors": [
+        "(1,10): XXX-undefined-error",
+        "(1,13): unexpected-start-tag-implies-table-voodoo",
+        "(1,13): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<tbody><a>",
+      "errors": [
+        "(1,7): XXX-undefined-error",
+        "(1,10): unexpected-start-tag-implies-table-voodoo",
+        "(1,10): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<tfoot><a>",
+      "errors": [
+        "(1,7): XXX-undefined-error",
+        "(1,10): unexpected-start-tag-implies-table-voodoo",
+        "(1,10): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<thead><a>",
+      "errors": [
+        "(1,7): XXX-undefined-error",
+        "(1,10): unexpected-start-tag-implies-table-voodoo",
+        "(1,10): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "</table><a>",
+      "errors": [
+        "(1,8): XXX-undefined-error",
+        "(1,11): unexpected-start-tag-implies-table-voodoo",
+        "(1,11): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><tr>",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tr"
+          }
+        ],
+        "html": "<a></a><tr></tr>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><td>",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo",
+        "(1,7): unexpected-cell-in-table-body"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tr",
+            "children": [
+              {
+                "tag": "td"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><tr><td></td></tr>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><td>",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo",
+        "(1,7): unexpected-cell-in-table-body"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tr",
+            "children": [
+              {
+                "tag": "td"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><tr><td></td></tr>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<a><td>",
+      "errors": [
+        "(1,3): unexpected-start-tag-implies-table-voodoo",
+        "(1,7): unexpected-cell-in-table-body"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          },
+          {
+            "tag": "tr",
+            "children": [
+              {
+                "tag": "td"
+              }
+            ]
+          }
+        ],
+        "html": "<a></a><tr><td></td></tr>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<td><table><tbody><a><tr>",
+      "errors": [
+        "(1,4): unexpected-cell-in-table-body",
+        "(1,21): unexpected-start-tag-implies-table-voodoo",
+        "(1,25): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "tr": true,
+            "td": true,
+            "a": true,
+            "table": true,
+            "tbody": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "tr",
+            "children": [
+              {
+                "tag": "td",
+                "children": [
+                  {
+                    "tag": "a"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<tr><td><a></a><table><tbody><tr></tr></tbody></table></td></tr>",
+        "noQuirksBodyHtml": "<a></a><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "</tr><td>",
+      "errors": [
+        "(1,5): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<td><table><a><tr></tr><tr>",
+      "errors": [
+        "(1,14): unexpected-start-tag-implies-table-voodoo",
+        "(1,27): eof-in-table"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td",
+            "children": [
+              {
+                "tag": "a"
+              },
+              {
+                "tag": "table",
+                "children": [
+                  {
+                    "tag": "tbody",
+                    "children": [
+                      {
+                        "tag": "tr"
+                      },
+                      {
+                        "tag": "tr"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<td><a></a><table><tbody><tr></tr><tr></tr></tbody></table></td>",
+        "noQuirksBodyHtml": "<a></a><table><tbody><tr></tr><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<caption><td>",
+      "errors": [
+        "(1,9): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<col><td>",
+      "errors": [
+        "(1,5): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<colgroup><td>",
+      "errors": [
+        "(1,10): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<tbody><td>",
+      "errors": [
+        "(1,7): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<tfoot><td>",
+      "errors": [
+        "(1,7): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<thead><td>",
+      "errors": [
+        "(1,7): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<tr><td>",
+      "errors": [
+        "(1,4): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "</table><td>",
+      "errors": [
+        "(1,8): XXX-undefined-error"
+      ],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td></td>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<td><table></table><td>",
+      "errors": [],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td",
+            "children": [
+              {
+                "tag": "table"
+              }
+            ]
+          },
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td><table></table></td><td></td>",
+        "noQuirksBodyHtml": "<table></table>"
+      }
+    },
+    {
+      "data": "<td><table></table><td>",
+      "errors": [],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "td": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "td",
+            "children": [
+              {
+                "tag": "table"
+              }
+            ]
+          },
+          {
+            "tag": "td"
+          }
+        ],
+        "html": "<td><table></table></td><td></td>",
+        "noQuirksBodyHtml": "<table></table>"
+      }
+    },
+    {
+      "data": "<caption><a>",
+      "errors": [
+        "(1,9): XXX-undefined-error",
+        "(1,12): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<col><a>",
+      "errors": [
+        "(1,5): XXX-undefined-error",
+        "(1,8): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<colgroup><a>",
+      "errors": [
+        "(1,10): XXX-undefined-error",
+        "(1,13): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<tbody><a>",
+      "errors": [
+        "(1,7): XXX-undefined-error",
+        "(1,10): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<tfoot><a>",
+      "errors": [
+        "(1,7): XXX-undefined-error",
+        "(1,10): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<th><a>",
+      "errors": [
+        "(1,4): XXX-undefined-error",
+        "(1,7): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<thead><a>",
+      "errors": [
+        "(1,7): XXX-undefined-error",
+        "(1,10): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<tr><a>",
+      "errors": [
+        "(1,4): XXX-undefined-error",
+        "(1,7): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "</table><a>",
+      "errors": [
+        "(1,8): XXX-undefined-error",
+        "(1,11): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "</tbody><a>",
+      "errors": [
+        "(1,8): XXX-undefined-error",
+        "(1,11): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "</td><a>",
+      "errors": [
+        "(1,5): unexpected-end-tag",
+        "(1,8): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "</tfoot><a>",
+      "errors": [
+        "(1,8): XXX-undefined-error",
+        "(1,11): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "</thead><a>",
+      "errors": [
+        "(1,8): XXX-undefined-error",
+        "(1,11): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "</th><a>",
+      "errors": [
+        "(1,5): unexpected-end-tag",
+        "(1,8): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "</tr><a>",
+      "errors": [
+        "(1,5): XXX-undefined-error",
+        "(1,8): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "a"
+          }
+        ],
+        "html": "<a></a>",
+        "noQuirksBodyHtml": "<a></a>"
+      }
+    },
+    {
+      "data": "<table><td><td>",
+      "errors": [
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,15): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "table",
+            "children": [
+              {
+                "tag": "tbody",
+                "children": [
+                  {
+                    "tag": "tr",
+                    "children": [
+                      {
+                        "tag": "td"
+                      },
+                      {
+                        "tag": "td"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<table><tbody><tr><td></td><td></td></tr></tbody></table>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td></td><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "</select><option>",
+      "errors": [
+        "(1,9): XXX-undefined-error",
+        "(1,17): eof-in-select"
+      ],
+      "fragment": {
+        "name": "select"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "option"
+          }
+        ],
+        "html": "<option></option>",
+        "noQuirksBodyHtml": "<option></option>"
+      }
+    },
+    {
+      "data": "<input><option>",
+      "errors": [
+        "(1,7): unexpected-input-in-select",
+        "(1,15): eof-in-select"
+      ],
+      "fragment": {
+        "name": "select"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "option"
+          }
+        ],
+        "html": "<option></option>",
+        "noQuirksBodyHtml": "<input><option></option>"
+      }
+    },
+    {
+      "data": "<keygen><option>",
+      "errors": [
+        "(1,8): unexpected-input-in-select",
+        "(1,16): eof-in-select"
+      ],
+      "fragment": {
+        "name": "select"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "option"
+          }
+        ],
+        "html": "<option></option>",
+        "noQuirksBodyHtml": "<keygen><option></option>"
+      }
+    },
+    {
+      "data": "<textarea><option>",
+      "errors": [
+        "(1,10): unexpected-input-in-select",
+        "(1,18): eof-in-select"
+      ],
+      "fragment": {
+        "name": "select"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "option"
+          }
+        ],
+        "html": "<option></option>",
+        "noQuirksBodyHtml": "<textarea>&lt;option&gt;</textarea>"
+      }
+    },
+    {
+      "data": "</html><!--abc-->",
+      "errors": [
+        "(1,7): unexpected-end-tag-after-body-innerhtml"
+      ],
+      "fragment": {
+        "name": "html"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "head"
+          },
+          {
+            "tag": "body"
+          },
+          {
+            "comment": "abc"
+          }
+        ],
+        "html": "<head></head><body></body><!--abc-->",
+        "noQuirksBodyHtml": "<!--abc-->"
+      }
+    },
+    {
+      "data": "</frameset><frame>",
+      "errors": [
+        "(1,11): unexpected-frameset-in-frameset-innerhtml"
+      ],
+      "fragment": {
+        "name": "frameset"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "frame": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "frame"
+          }
+        ],
+        "html": "<frame>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "",
+      "errors": [],
+      "fragment": {
+        "name": "html"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "head"
+          },
+          {
+            "tag": "body"
+          }
+        ],
+        "html": "<head></head><body></body>",
+        "noQuirksBodyHtml": ""
+      }
+    }
+  ],
+  "tricky01.dat": [
+    {
+      "data": "<b><p>Bold </b> Not bold</p>\nAlso not bold.",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,15): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "text": "Bold "
+                          }
+                        ]
+                      },
+                      {
+                        "text": " Not bold"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "\nAlso not bold."
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b></b><p><b>Bold </b> Not bold</p>\nAlso not bold.</body></html>",
+        "noQuirksBodyHtml": "<b></b><p><b>Bold </b> Not bold</p>\nAlso not bold."
+      }
+    },
+    {
+      "data": "<html>\n<font color=red><i>Italic and Red<p>Italic and Red </font> Just italic.</p> Italic only.</i> Plain\n<p>I should not be red. <font color=red>Red. <i>Italic and red.</p>\n<p>Italic and red. </i> Red.</font> I should not be red.</p>\n<b>Bold <i>Bold and italic</b> Only Italic </i> Plain",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(2,58): adoption-agency-1.3",
+        "(3,67): unexpected-end-tag",
+        "(4,23): adoption-agency-1.3",
+        "(4,35): adoption-agency-1.3",
+        "(5,30): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "font": true,
+            "i": true,
+            "p": true,
+            "b": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "font",
+                    "attrs": [
+                      {
+                        "name": "color",
+                        "value": "red"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "text": "Italic and Red"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "tag": "font",
+                            "attrs": [
+                              {
+                                "name": "color",
+                                "value": "red"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "text": "Italic and Red "
+                              }
+                            ]
+                          },
+                          {
+                            "text": " Just italic."
+                          }
+                        ]
+                      },
+                      {
+                        "text": " Italic only."
+                      }
+                    ]
+                  },
+                  {
+                    "text": " Plain\n"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "I should not be red. "
+                      },
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "color",
+                            "value": "red"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "text": "Red. "
+                          },
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "Italic and red."
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "font",
+                    "attrs": [
+                      {
+                        "name": "color",
+                        "value": "red"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "text": "\n"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "color",
+                            "value": "red"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "Italic and red. "
+                              }
+                            ]
+                          },
+                          {
+                            "text": " Red."
+                          }
+                        ]
+                      },
+                      {
+                        "text": " I should not be red."
+                      }
+                    ]
+                  },
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "Bold "
+                      },
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "text": "Bold and italic"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "i",
+                    "children": [
+                      {
+                        "text": " Only Italic "
+                      }
+                    ]
+                  },
+                  {
+                    "text": " Plain"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><font color=\"red\"><i>Italic and Red</i></font><i><p><font color=\"red\">Italic and Red </font> Just italic.</p> Italic only.</i> Plain\n<p>I should not be red. <font color=\"red\">Red. <i>Italic and red.</i></font></p><font color=\"red\"><i>\n</i></font><p><font color=\"red\"><i>Italic and red. </i> Red.</font> I should not be red.</p>\n<b>Bold <i>Bold and italic</i></b><i> Only Italic </i> Plain</body></html>",
+        "noQuirksBodyHtml": "\n<font color=\"red\"><i>Italic and Red</i></font><i><p><font color=\"red\">Italic and Red </font> Just italic.</p> Italic only.</i> Plain\n<p>I should not be red. <font color=\"red\">Red. <i>Italic and red.</i></font></p><font color=\"red\"><i>\n</i></font><p><font color=\"red\"><i>Italic and red. </i> Red.</font> I should not be red.</p>\n<b>Bold <i>Bold and italic</i></b><i> Only Italic </i> Plain"
+      }
+    },
+    {
+      "data": "<html><body>\n<p><font size=\"7\">First paragraph.</p>\n<p>Second paragraph.</p></font>\n<b><p><i>Bold and Italic</b> Italic</p>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(2,38): unexpected-end-tag",
+        "(4,28): adoption-agency-1.3",
+        "(4,28): adoption-agency-1.3",
+        "(4,39): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "font": true,
+            "b": true,
+            "i": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "attrs": [
+                          {
+                            "name": "size",
+                            "value": "7"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "text": "First paragraph."
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "font",
+                    "attrs": [
+                      {
+                        "name": "size",
+                        "value": "7"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "\n"
+                      },
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "Second paragraph."
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "b"
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "i",
+                            "children": [
+                              {
+                                "text": "Bold and Italic"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "i",
+                        "children": [
+                          {
+                            "text": " Italic"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>\n<p><font size=\"7\">First paragraph.</font></p><font size=\"7\">\n<p>Second paragraph.</p></font>\n<b></b><p><b><i>Bold and Italic</i></b><i> Italic</i></p></body></html>",
+        "noQuirksBodyHtml": "\n<p><font size=\"7\">First paragraph.</font></p><font size=\"7\">\n<p>Second paragraph.</p></font>\n<b></b><p><b><i>Bold and Italic</i></b><i> Italic</i></p>"
+      }
+    },
+    {
+      "data": "<html>\n<dl>\n<dt><b>Boo\n<dd>Goo?\n</dl>\n</html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(4,4): end-tag-too-early",
+        "(5,5): end-tag-too-early",
+        "(6,7): expected-one-end-tag-but-got-another"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dl": true,
+            "dt": true,
+            "b": true,
+            "dd": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dl",
+                    "children": [
+                      {
+                        "text": "\n"
+                      },
+                      {
+                        "tag": "dt",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "text": "Boo\n"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "dd",
+                        "children": [
+                          {
+                            "tag": "b",
+                            "children": [
+                              {
+                                "text": "Goo?\n"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "text": "\n"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><dl>\n<dt><b>Boo\n</b></dt><dd><b>Goo?\n</b></dd></dl><b>\n</b></body></html>",
+        "noQuirksBodyHtml": "\n<dl>\n<dt><b>Boo\n</b></dt><dd><b>Goo?\n</b></dd></dl><b>\n</b>"
+      }
+    },
+    {
+      "data": "<html><body>\n<label><a><div>Hello<div>World</div></a></label>  \n</body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(2,40): adoption-agency-1.3",
+        "(2,48): unexpected-end-tag",
+        "(3,7): expected-one-end-tag-but-got-another"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "label": true,
+            "a": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "label",
+                    "children": [
+                      {
+                        "tag": "a"
+                      },
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "a",
+                            "children": [
+                              {
+                                "text": "Hello"
+                              },
+                              {
+                                "tag": "div",
+                                "children": [
+                                  {
+                                    "text": "World"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "text": "  \n"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>\n<label><a></a><div><a>Hello<div>World</div></a>  \n</div></label></body></html>",
+        "noQuirksBodyHtml": "\n<label><a></a><div><a>Hello<div>World</div></a>  \n</div></label>"
+      }
+    },
+    {
+      "data": "<table><center> <font>a</center> <img> <tr><td> </td> </tr> </table>",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,15): foster-parenting-start-tag",
+        "(1,16): foster-parenting-character",
+        "(1,22): foster-parenting-start-tag",
+        "(1,23): foster-parenting-character",
+        "(1,32): foster-parenting-end-tag",
+        "(1,32): end-tag-too-early",
+        "(1,33): foster-parenting-character",
+        "(1,38): foster-parenting-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "center": true,
+            "font": true,
+            "img": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "center",
+                    "children": [
+                      {
+                        "text": " "
+                      },
+                      {
+                        "tag": "font",
+                        "children": [
+                          {
+                            "text": "a"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "font",
+                    "children": [
+                      {
+                        "tag": "img"
+                      },
+                      {
+                        "text": " "
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "text": " "
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": " "
+                                  }
+                                ]
+                              },
+                              {
+                                "text": " "
+                              }
+                            ]
+                          },
+                          {
+                            "text": " "
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><center> <font>a</font></center><font><img> </font><table> <tbody><tr><td> </td> </tr> </tbody></table></body></html>",
+        "noQuirksBodyHtml": "<center> <font>a</font></center><font><img> </font><table> <tbody><tr><td> </td> </tr> </tbody></table>"
+      }
+    },
+    {
+      "data": "<table><tr><p><a><p>You should see this text.",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,14): unexpected-start-tag-implies-table-voodoo",
+        "(1,17): unexpected-start-tag-implies-table-voodoo",
+        "(1,20): unexpected-start-tag-implies-table-voodoo",
+        "(1,20): closing-non-current-p-element",
+        "(1,21): foster-parenting-character",
+        "(1,22): foster-parenting-character",
+        "(1,23): foster-parenting-character",
+        "(1,24): foster-parenting-character",
+        "(1,25): foster-parenting-character",
+        "(1,26): foster-parenting-character",
+        "(1,27): foster-parenting-character",
+        "(1,28): foster-parenting-character",
+        "(1,29): foster-parenting-character",
+        "(1,30): foster-parenting-character",
+        "(1,31): foster-parenting-character",
+        "(1,32): foster-parenting-character",
+        "(1,33): foster-parenting-character",
+        "(1,34): foster-parenting-character",
+        "(1,35): foster-parenting-character",
+        "(1,36): foster-parenting-character",
+        "(1,37): foster-parenting-character",
+        "(1,38): foster-parenting-character",
+        "(1,39): foster-parenting-character",
+        "(1,40): foster-parenting-character",
+        "(1,41): foster-parenting-character",
+        "(1,42): foster-parenting-character",
+        "(1,43): foster-parenting-character",
+        "(1,44): foster-parenting-character",
+        "(1,45): foster-parenting-character",
+        "(1,45): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "a": true,
+            "table": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "text": "You should see this text."
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p><a></a></p><p><a>You should see this text.</a></p><table><tbody><tr></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<p><a></a></p><p><a>You should see this text.</a></p><table><tbody><tr></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<TABLE>\n<TR>\n<CENTER><CENTER><TD></TD></TR><TR>\n<FONT>\n<TABLE><tr></tr></TABLE>\n</P>\n<a></font><font></a>\nThis page contains an insanely badly-nested tag sequence.",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(3,8): unexpected-start-tag-implies-table-voodoo",
+        "(3,16): unexpected-start-tag-implies-table-voodoo",
+        "(4,6): unexpected-start-tag-implies-table-voodoo",
+        "(4,6): unexpected character token in table (the newline)",
+        "(5,7): unexpected-start-tag-implies-end-tag",
+        "(6,4): unexpected p end tag",
+        "(7,10): adoption-agency-1.3",
+        "(7,20): adoption-agency-1.3",
+        "(8,57): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "center": true,
+            "font": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "p": true,
+            "a": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "center",
+                    "children": [
+                      {
+                        "tag": "center"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "font",
+                    "children": [
+                      {
+                        "text": "\n"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "text": "\n"
+                      },
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "text": "\n"
+                              },
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "text": "\n"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "font",
+                    "children": [
+                      {
+                        "text": "\n"
+                      },
+                      {
+                        "tag": "p"
+                      },
+                      {
+                        "text": "\n"
+                      },
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "tag": "font"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "font",
+                    "children": [
+                      {
+                        "text": "\nThis page contains an insanely badly-nested tag sequence."
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><center><center></center></center><font>\n</font><table>\n<tbody><tr>\n<td></td></tr><tr>\n</tr></tbody></table><table><tbody><tr></tr></tbody></table><font>\n<p></p>\n<a></a></font><a><font></font></a><font>\nThis page contains an insanely badly-nested tag sequence.</font></body></html>",
+        "noQuirksBodyHtml": "<center><center></center></center><font>\n</font><table>\n<tbody><tr>\n<td></td></tr><tr>\n</tr></tbody></table><table><tbody><tr></tr></tbody></table><font>\n<p></p>\n<a></a></font><a><font></font></a><font>\nThis page contains an insanely badly-nested tag sequence.</font>"
+      }
+    },
+    {
+      "data": "<html>\n<body>\n<b><nobr><div>This text is in a div inside a nobr</nobr>More text that should not be in the nobr, i.e., the\nnobr should have closed the div inside it implicitly. </b><pre>A pre tag outside everything else.</pre>\n</body>\n</html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(3,56): adoption-agency-1.3",
+        "(4,58): adoption-agency-1.3",
+        "(5,7): expected-one-end-tag-but-got-another"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "nobr": true,
+            "div": true,
+            "pre": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "nobr"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "nobr",
+                            "children": [
+                              {
+                                "text": "This text is in a div inside a nobr"
+                              }
+                            ]
+                          },
+                          {
+                            "text": "More text that should not be in the nobr, i.e., the\nnobr should have closed the div inside it implicitly. "
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "pre",
+                        "children": [
+                          {
+                            "text": "A pre tag outside everything else."
+                          }
+                        ]
+                      },
+                      {
+                        "text": "\n\n"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>\n<b><nobr></nobr></b><div><b><nobr>This text is in a div inside a nobr</nobr>More text that should not be in the nobr, i.e., the\nnobr should have closed the div inside it implicitly. </b><pre>A pre tag outside everything else.</pre>\n\n</div></body></html>",
+        "noQuirksBodyHtml": "\n\n<b><nobr></nobr></b><div><b><nobr>This text is in a div inside a nobr</nobr>More text that should not be in the nobr, i.e., the\nnobr should have closed the div inside it implicitly. </b><pre>A pre tag outside everything else.</pre>\n\n</div>"
+      }
+    }
+  ],
+  "webkit01.dat": [
+    {
+      "data": "Test",
+      "errors": [
+        "(1,4): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Test"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>Test</body></html>",
+        "noQuirksBodyHtml": "Test"
+      }
+    },
+    {
+      "data": "<div></div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div></div></body></html>",
+        "noQuirksBodyHtml": "<div></div>"
+      }
+    },
+    {
+      "data": "<div>Test</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "Test"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>Test</div></body></html>",
+        "noQuirksBodyHtml": "<div>Test</div>"
+      }
+    },
+    {
+      "data": "<di",
+      "errors": [
+        "(1,3): eof-in-tag-name",
+        "(1,3): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<div>Hello</div>\n<script>\nconsole.log(\"PASS\");\n</script>\n<div>Bye</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "Hello"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "\nconsole.log(\"PASS\");\n",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "Bye"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>Hello</div>\n<script>\nconsole.log(\"PASS\");\n</script>\n<div>Bye</div></body></html>",
+        "noQuirksBodyHtml": "<div>Hello</div>\n<script>\nconsole.log(\"PASS\");\n</script>\n<div>Bye</div>"
+      }
+    },
+    {
+      "data": "<div foo=\"bar\">Hello</div>",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "foo",
+                        "value": "bar"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "text": "Hello"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div foo=\"bar\">Hello</div></body></html>",
+        "noQuirksBodyHtml": "<div foo=\"bar\">Hello</div>"
+      }
+    },
+    {
+      "data": "<div>Hello</div>\n<script>\nconsole.log(\"FOO<span>BAR</span>BAZ\");\n</script>\n<div>Bye</div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "script": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "Hello"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "script",
+                    "children": [
+                      {
+                        "text": "\nconsole.log(\"FOO<span>BAR</span>BAZ\");\n",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "text": "\n"
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "text": "Bye"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div>Hello</div>\n<script>\nconsole.log(\"FOO<span>BAR</span>BAZ\");\n</script>\n<div>Bye</div></body></html>",
+        "noQuirksBodyHtml": "<div>Hello</div>\n<script>\nconsole.log(\"FOO<span>BAR</span>BAZ\");\n</script>\n<div>Bye</div>"
+      }
+    },
+    {
+      "data": "<foo bar=\"baz\"></foo><potato quack=\"duck\"></potato>",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "foo": true,
+            "potato": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "baz"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "potato",
+                    "attrs": [
+                      {
+                        "name": "quack",
+                        "value": "duck"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><foo bar=\"baz\"></foo><potato quack=\"duck\"></potato></body></html>",
+        "noQuirksBodyHtml": "<foo bar=\"baz\"></foo><potato quack=\"duck\"></potato>"
+      }
+    },
+    {
+      "data": "<foo bar=\"baz\"><potato quack=\"duck\"></potato></foo>",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "foo": true,
+            "potato": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "baz"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "potato",
+                        "attrs": [
+                          {
+                            "name": "quack",
+                            "value": "duck"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><foo bar=\"baz\"><potato quack=\"duck\"></potato></foo></body></html>",
+        "noQuirksBodyHtml": "<foo bar=\"baz\"><potato quack=\"duck\"></potato></foo>"
+      }
+    },
+    {
+      "data": "<foo></foo bar=\"baz\"><potato></potato quack=\"duck\">",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,21): attributes-in-end-tag",
+        "(1,51): attributes-in-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "foo": true,
+            "potato": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "foo"
+                  },
+                  {
+                    "tag": "potato"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><foo></foo><potato></potato></body></html>",
+        "noQuirksBodyHtml": "<foo></foo><potato></potato>"
+      }
+    },
+    {
+      "data": "</ tttt>",
+      "errors": [
+        "(1,2): expected-closing-tag-but-got-char",
+        "(1,8): expected-doctype-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "comment": " tttt"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!-- tttt--><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": "<!-- tttt-->"
+      }
+    },
+    {
+      "data": "<div FOO ><img><img></div>",
+      "errors": [
+        "(1,10): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "img": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "attrs": [
+                      {
+                        "name": "foo",
+                        "value": ""
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "img"
+                      },
+                      {
+                        "tag": "img"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div foo=\"\"><img><img></div></body></html>",
+        "noQuirksBodyHtml": "<div foo=\"\"><img><img></div>"
+      }
+    },
+    {
+      "data": "<p>Test</p<p>Test2</p>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,13): unexpected-end-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "text": "TestTest2"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p>TestTest2</p></body></html>",
+        "noQuirksBodyHtml": "<p>TestTest2</p>"
+      }
+    },
+    {
+      "data": "<rdar://problem/6869687>",
+      "errors": [
+        "(1,7): unexpected-character-after-solidus-in-tag",
+        "(1,8): unexpected-character-after-solidus-in-tag",
+        "(1,16): unexpected-character-after-solidus-in-tag",
+        "(1,24): expected-doctype-but-got-start-tag",
+        "(1,24): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "rdar:": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "rdar:",
+                    "attrs": [
+                      {
+                        "name": "6869687",
+                        "value": ""
+                      },
+                      {
+                        "name": "problem",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><rdar: problem=\"\" 6869687=\"\"></rdar:></body></html>",
+        "noQuirksBodyHtml": "<rdar: problem=\"\" 6869687=\"\"></rdar:>"
+      }
+    },
+    {
+      "data": "<A>test< /A>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,8): expected-tag-name",
+        "(1,12): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a",
+                    "children": [
+                      {
+                        "text": "test< /A>",
+                        "escaped": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a>test&lt; /A&gt;</a></body></html>",
+        "noQuirksBodyHtml": "<a>test&lt; /A&gt;</a>"
+      }
+    },
+    {
+      "data": "&lt;",
+      "errors": [
+        "(1,4): expected-doctype-but-got-chars"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "escaped": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "<",
+                    "escaped": true
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>&lt;</body></html>",
+        "noQuirksBodyHtml": "&lt;"
+      }
+    },
+    {
+      "data": "<body foo='bar'><body foo='baz' yo='mama'>",
+      "errors": [
+        "(1,16): expected-doctype-but-got-start-tag",
+        "(1,42): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "attrs": [
+                  {
+                    "name": "foo",
+                    "value": "bar"
+                  },
+                  {
+                    "name": "yo",
+                    "value": "mama"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body foo=\"bar\" yo=\"mama\"></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<body></br foo=\"bar\"></body>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,21): attributes-in-end-tag",
+        "(1,21): unexpected-end-tag-treated-as"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "br": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "br"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><br></body></html>",
+        "noQuirksBodyHtml": "<br>"
+      }
+    },
+    {
+      "data": "<bdy><br foo=\"bar\"></body>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,26): expected-one-end-tag-but-got-another"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "bdy": true,
+            "br": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "bdy",
+                    "children": [
+                      {
+                        "tag": "br",
+                        "attrs": [
+                          {
+                            "name": "foo",
+                            "value": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><bdy><br foo=\"bar\"></bdy></body></html>",
+        "noQuirksBodyHtml": "<bdy><br foo=\"bar\"></bdy>"
+      }
+    },
+    {
+      "data": "<body></body></br foo=\"bar\">",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,28): attributes-in-end-tag",
+        "(1,28): unexpected-end-tag-after-body",
+        "(1,28): unexpected-end-tag-treated-as"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "br": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "br"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><br></body></html>",
+        "noQuirksBodyHtml": "<br>"
+      }
+    },
+    {
+      "data": "<bdy></body><br foo=\"bar\">",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,12): expected-one-end-tag-but-got-another",
+        "(1,26): unexpected-start-tag-after-body",
+        "(1,26): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "bdy": true,
+            "br": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "bdy",
+                    "children": [
+                      {
+                        "tag": "br",
+                        "attrs": [
+                          {
+                            "name": "foo",
+                            "value": "bar"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><bdy><br foo=\"bar\"></bdy></body></html>",
+        "noQuirksBodyHtml": "<bdy><br foo=\"bar\"></bdy>"
+      }
+    },
+    {
+      "data": "<html><body></body></html><!-- Hi there -->",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          },
+          {
+            "comment": " Hi there "
+          }
+        ],
+        "html": "<html><head></head><body></body></html><!-- Hi there -->",
+        "noQuirksBodyHtml": "<!-- Hi there -->"
+      }
+    },
+    {
+      "data": "<html><body></body></html>x<!-- Hi there -->",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,27): expected-eof-but-got-char"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  },
+                  {
+                    "comment": " Hi there "
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>x<!-- Hi there --></body></html>",
+        "noQuirksBodyHtml": "x<!-- Hi there -->"
+      }
+    },
+    {
+      "data": "<html><body></body></html>x<!-- Hi there --></html><!-- Again -->",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,27): expected-eof-but-got-char"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  },
+                  {
+                    "comment": " Hi there "
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "comment": " Again "
+          }
+        ],
+        "html": "<html><head></head><body>x<!-- Hi there --></body></html><!-- Again -->",
+        "noQuirksBodyHtml": "x<!-- Hi there --><!-- Again -->"
+      }
+    },
+    {
+      "data": "<html><body></body></html>x<!-- Hi there --></body></html><!-- Again -->",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,27): expected-eof-but-got-char"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "x"
+                  },
+                  {
+                    "comment": " Hi there "
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "comment": " Again "
+          }
+        ],
+        "html": "<html><head></head><body>x<!-- Hi there --></body></html><!-- Again -->",
+        "noQuirksBodyHtml": "x<!-- Hi there --><!-- Again -->"
+      }
+    },
+    {
+      "data": "<html><body><ruby><div><rp>xx</rp></div></ruby></body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,27): XXX-undefined-error"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "div": true,
+            "rp": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "rp",
+                            "children": [
+                              {
+                                "text": "xx"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby><div><rp>xx</rp></div></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><div><rp>xx</rp></div></ruby>"
+      }
+    },
+    {
+      "data": "<html><body><ruby><div><rt>xx</rt></div></ruby></body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,27): XXX-undefined-error"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ruby": true,
+            "div": true,
+            "rt": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ruby",
+                    "children": [
+                      {
+                        "tag": "div",
+                        "children": [
+                          {
+                            "tag": "rt",
+                            "children": [
+                              {
+                                "text": "xx"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ruby><div><rt>xx</rt></div></ruby></body></html>",
+        "noQuirksBodyHtml": "<ruby><div><rt>xx</rt></div></ruby>"
+      }
+    },
+    {
+      "data": "<html><frameset><!--1--><noframes>A</noframes><!--2--></frameset><!--3--><noframes>B</noframes><!--4--></html><!--5--><noframes>C</noframes><!--6-->",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true,
+            "noframes": true
+          },
+          "comment": true,
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset",
+                "children": [
+                  {
+                    "comment": "1"
+                  },
+                  {
+                    "tag": "noframes",
+                    "children": [
+                      {
+                        "text": "A",
+                        "no_escape": true
+                      }
+                    ]
+                  },
+                  {
+                    "comment": "2"
+                  }
+                ]
+              },
+              {
+                "comment": "3"
+              },
+              {
+                "tag": "noframes",
+                "children": [
+                  {
+                    "text": "B",
+                    "no_escape": true
+                  }
+                ]
+              },
+              {
+                "comment": "4"
+              },
+              {
+                "tag": "noframes",
+                "children": [
+                  {
+                    "text": "C",
+                    "no_escape": true
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "comment": "5"
+          },
+          {
+            "comment": "6"
+          }
+        ],
+        "html": "<html><head></head><frameset><!--1--><noframes>A</noframes><!--2--></frameset><!--3--><noframes>B</noframes><!--4--><noframes>C</noframes></html><!--5--><!--6-->",
+        "noQuirksBodyHtml": "<!--1--><noframes>A</noframes><!--2--><!--3--><noframes>B</noframes><!--4--><!--5--><noframes>C</noframes><!--6-->"
+      }
+    },
+    {
+      "data": "<select><option>A<select><option>B<select><option>C<select><option>D<select><option>E<select><option>F<select><option>G<select>",
+      "errors": [
+        "(1,8): expected-doctype-but-got-start-tag",
+        "(1,25): unexpected-select-in-select",
+        "(1,59): unexpected-select-in-select",
+        "(1,93): unexpected-select-in-select",
+        "(1,127): unexpected-select-in-select",
+        "(1,127): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true,
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select",
+                    "children": [
+                      {
+                        "tag": "option",
+                        "children": [
+                          {
+                            "text": "A"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "option",
+                    "children": [
+                      {
+                        "text": "B"
+                      },
+                      {
+                        "tag": "select",
+                        "children": [
+                          {
+                            "tag": "option",
+                            "children": [
+                              {
+                                "text": "C"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "option",
+                    "children": [
+                      {
+                        "text": "D"
+                      },
+                      {
+                        "tag": "select",
+                        "children": [
+                          {
+                            "tag": "option",
+                            "children": [
+                              {
+                                "text": "E"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "option",
+                    "children": [
+                      {
+                        "text": "F"
+                      },
+                      {
+                        "tag": "select",
+                        "children": [
+                          {
+                            "tag": "option",
+                            "children": [
+                              {
+                                "text": "G"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><select><option>A</option></select><option>B<select><option>C</option></select></option><option>D<select><option>E</option></select></option><option>F<select><option>G</option></select></option></body></html>",
+        "noQuirksBodyHtml": "<select><option>A</option></select><option>B<select><option>C</option></select></option><option>D<select><option>E</option></select></option><option>F<select><option>G</option></select></option>"
+      }
+    },
+    {
+      "data": "<dd><dd><dt><dt><dd><li><li>",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "dd": true,
+            "dt": true,
+            "li": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "dd"
+                  },
+                  {
+                    "tag": "dd"
+                  },
+                  {
+                    "tag": "dt"
+                  },
+                  {
+                    "tag": "dt"
+                  },
+                  {
+                    "tag": "dd",
+                    "children": [
+                      {
+                        "tag": "li"
+                      },
+                      {
+                        "tag": "li"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><dd></dd><dd></dd><dt></dt><dt></dt><dd><li></li><li></li></dd></body></html>",
+        "noQuirksBodyHtml": "<dd></dd><dd></dd><dt></dt><dt></dt><dd><li></li><li></li></dd>"
+      }
+    },
+    {
+      "data": "<div><b></div><div><nobr>a<nobr>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,14): end-tag-too-early",
+        "(1,32): unexpected-start-tag-implies-end-tag",
+        "(1,32): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "b": true,
+            "nobr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "b",
+                        "children": [
+                          {
+                            "tag": "nobr",
+                            "children": [
+                              {
+                                "text": "a"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "nobr"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><b></b></div><div><b><nobr>a</nobr><nobr></nobr></b></div></body></html>",
+        "noQuirksBodyHtml": "<div><b></b></div><div><b><nobr>a</nobr><nobr></nobr></b></div>"
+      }
+    },
+    {
+      "data": "<head></head>\n<body></body>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "text": "\n"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head>\n<body></body></html>",
+        "noQuirksBodyHtml": "\n"
+      }
+    },
+    {
+      "data": "<head></head> <style></style>ddd",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,21): unexpected-start-tag-out-of-my-head"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "style": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "style"
+                  }
+                ]
+              },
+              {
+                "text": " "
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "ddd"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><style></style></head> <body>ddd</body></html>",
+        "noQuirksBodyHtml": " <style></style>ddd"
+      }
+    },
+    {
+      "data": "<kbd><table></kbd><col><select><tr>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,18): unexpected-end-tag-implies-table-voodoo",
+        "(1,18): unexpected-end-tag",
+        "(1,31): unexpected-start-tag-implies-table-voodoo",
+        "(1,35): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,35): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "kbd": true,
+            "select": true,
+            "table": true,
+            "colgroup": true,
+            "col": true,
+            "tbody": true,
+            "tr": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "kbd",
+                    "children": [
+                      {
+                        "tag": "select"
+                      },
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "colgroup",
+                            "children": [
+                              {
+                                "tag": "col"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><kbd><select></select><table><colgroup><col></colgroup><tbody><tr></tr></tbody></table></kbd></body></html>",
+        "noQuirksBodyHtml": "<kbd><select></select><table><colgroup><col></colgroup><tbody><tr></tr></tbody></table></kbd>"
+      }
+    },
+    {
+      "data": "<kbd><table></kbd><col><select><tr></table><div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,18): unexpected-end-tag-implies-table-voodoo",
+        "(1,18): unexpected-end-tag",
+        "(1,31): unexpected-start-tag-implies-table-voodoo",
+        "(1,35): unexpected-table-element-start-tag-in-select-in-table",
+        "(1,48): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "kbd": true,
+            "select": true,
+            "table": true,
+            "colgroup": true,
+            "col": true,
+            "tbody": true,
+            "tr": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "kbd",
+                    "children": [
+                      {
+                        "tag": "select"
+                      },
+                      {
+                        "tag": "table",
+                        "children": [
+                          {
+                            "tag": "colgroup",
+                            "children": [
+                              {
+                                "tag": "col"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "tbody",
+                            "children": [
+                              {
+                                "tag": "tr"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "div"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><kbd><select></select><table><colgroup><col></colgroup><tbody><tr></tr></tbody></table><div></div></kbd></body></html>",
+        "noQuirksBodyHtml": "<kbd><select></select><table><colgroup><col></colgroup><tbody><tr></tr></tbody></table><div></div></kbd>"
+      }
+    },
+    {
+      "data": "<a><li><style></style><title></title></a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,41): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "li": true,
+            "style": true,
+            "title": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a"
+                  },
+                  {
+                    "tag": "li",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "tag": "style"
+                          },
+                          {
+                            "tag": "title"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a></a><li><a><style></style><title></title></a></li></body></html>",
+        "noQuirksBodyHtml": "<a></a><li><a><style></style><title></title></a></li>"
+      }
+    },
+    {
+      "data": "<font></p><p><meta><title></title></font>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,10): unexpected-end-tag",
+        "(1,41): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "font": true,
+            "p": true,
+            "meta": true,
+            "title": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "font",
+                    "children": [
+                      {
+                        "tag": "p"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "font",
+                        "children": [
+                          {
+                            "tag": "meta"
+                          },
+                          {
+                            "tag": "title"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><font><p></p></font><p><font><meta><title></title></font></p></body></html>",
+        "noQuirksBodyHtml": "<font><p></p></font><p><font><meta><title></title></font></p>"
+      }
+    },
+    {
+      "data": "<a><center><title></title><a>",
+      "errors": [
+        "(1,3): expected-doctype-but-got-start-tag",
+        "(1,29): unexpected-start-tag-implies-end-tag",
+        "(1,29): adoption-agency-1.3",
+        "(1,29): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "a": true,
+            "center": true,
+            "title": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "a"
+                  },
+                  {
+                    "tag": "center",
+                    "children": [
+                      {
+                        "tag": "a",
+                        "children": [
+                          {
+                            "tag": "title"
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "a"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><a></a><center><a><title></title></a><a></a></center></body></html>",
+        "noQuirksBodyHtml": "<a></a><center><a><title></title></a><a></a></center>"
+      }
+    },
+    {
+      "data": "<svg><title><div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,17): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg title": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "title",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><title><div></div></title></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><title><div></div></title></svg>"
+      }
+    },
+    {
+      "data": "<svg><title><rect><div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,23): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg title": true,
+            "rect": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "title",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "rect",
+                            "children": [
+                              {
+                                "tag": "div"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><title><rect><div></div></rect></title></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><title><rect><div></div></rect></title></svg>"
+      }
+    },
+    {
+      "data": "<svg><title><svg><div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,22): unexpected-html-element-in-foreign-content",
+        "(1,22): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg title": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "title",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg"
+                          },
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><title><svg></svg><div></div></title></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><title><svg><div></div></svg></title></svg>"
+      }
+    },
+    {
+      "data": "<img <=\"\" FAIL>",
+      "errors": [
+        "(1,6): invalid-character-in-attribute-name",
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "img": true
+          },
+          "attrWithFunnyChar": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "img",
+                    "attrs": [
+                      {
+                        "name": "<",
+                        "value": ""
+                      },
+                      {
+                        "name": "fail",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><img <=\"\" fail=\"\"></body></html>",
+        "noQuirksBodyHtml": "<img <=\"\" fail=\"\">"
+      }
+    },
+    {
+      "data": "<ul><li><div id='foo'/>A</li><li>B<div>C</div></li></ul>",
+      "errors": [
+        "(1,4): expected-doctype-but-got-start-tag",
+        "(1,23): non-void-element-with-trailing-solidus",
+        "(1,29): end-tag-too-early"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "ul": true,
+            "li": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "ul",
+                    "children": [
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "tag": "div",
+                            "attrs": [
+                              {
+                                "name": "id",
+                                "value": "foo"
+                              }
+                            ],
+                            "children": [
+                              {
+                                "text": "A"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "li",
+                        "children": [
+                          {
+                            "text": "B"
+                          },
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "text": "C"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><ul><li><div id=\"foo\">A</div></li><li>B<div>C</div></li></ul></body></html>",
+        "noQuirksBodyHtml": "<ul><li><div id=\"foo\">A</div></li><li>B<div>C</div></li></ul>"
+      }
+    },
+    {
+      "data": "<svg><em><desc></em>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,9): unexpected-html-element-in-foreign-content",
+        "(1,20): adoption-agency-1.3"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "em": true,
+            "desc": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg"
+                  },
+                  {
+                    "tag": "em",
+                    "children": [
+                      {
+                        "tag": "desc"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg></svg><em><desc></desc></em></body></html>",
+        "noQuirksBodyHtml": "<svg><em><desc></desc></em></svg>"
+      }
+    },
+    {
+      "data": "<table><tr><td><svg><desc><td></desc><circle>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg desc": true,
+            "circle": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "desc",
+                                        "ns": "http://www.w3.org/2000/svg"
+                                      }
+                                    ]
+                                  }
+                                ]
+                              },
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "circle"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td><svg><desc></desc></svg></td><td><circle></circle></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td><svg><desc></desc></svg></td><td><circle></circle></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<svg><tfoot></mi><td>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag",
+        "(1,17): unexpected-end-tag",
+        "(1,17): unexpected-end-tag",
+        "(1,21): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg tfoot": true,
+            "svg td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "tfoot",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "td",
+                            "ns": "http://www.w3.org/2000/svg"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><tfoot><td></td></tfoot></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><tfoot><td></td></tfoot></svg>"
+      }
+    },
+    {
+      "data": "<math><mrow><mrow><mn>1</mn></mrow><mi>a</mi></mrow></math>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math mrow": true,
+            "math mn": true,
+            "math mi": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mrow",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "children": [
+                          {
+                            "tag": "mrow",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "tag": "mn",
+                                "ns": "http://www.w3.org/1998/Math/MathML",
+                                "children": [
+                                  {
+                                    "text": "1"
+                                  }
+                                ]
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "mi",
+                            "ns": "http://www.w3.org/1998/Math/MathML",
+                            "children": [
+                              {
+                                "text": "a"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><mrow><mrow><mn>1</mn></mrow><mi>a</mi></mrow></math></body></html>",
+        "noQuirksBodyHtml": "<math><mrow><mrow><mn>1</mn></mrow><mi>a</mi></mrow></math>"
+      }
+    },
+    {
+      "data": "<!doctype html><input type=\"hidden\"><frameset>",
+      "errors": [
+        "(1,46): unexpected-start-tag",
+        "(1,46): eof-in-frameset"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "frameset": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "frameset"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><frameset></frameset></html>",
+        "noQuirksBodyHtml": "<input type=\"hidden\">"
+      }
+    },
+    {
+      "data": "<!doctype html><input type=\"button\"><frameset>",
+      "errors": [
+        "(1,46): unexpected-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "input": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "input",
+                    "attrs": [
+                      {
+                        "name": "type",
+                        "value": "button"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><input type=\"button\"></body></html>",
+        "noQuirksBodyHtml": "<input type=\"button\">"
+      }
+    }
+  ],
+  "webkit02.dat": [
+    {
+      "data": "<foo bar=qux/>",
+      "errors": [
+        "(1,14): expected-doctype-but-got-start-tag",
+        "(1,14): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "foo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "attrs": [
+                      {
+                        "name": "bar",
+                        "value": "qux/"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><foo bar=\"qux/\"></foo></body></html>",
+        "noQuirksBodyHtml": "<foo bar=\"qux/\"></foo>"
+      }
+    },
+    {
+      "data": "<p id=\"status\"><noscript><strong>A</strong></noscript><span>B</span></p>",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "script": "on",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "noscript": true,
+            "span": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "attrs": [
+                      {
+                        "name": "id",
+                        "value": "status"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "noscript",
+                        "children": [
+                          {
+                            "text": "<strong>A</strong>",
+                            "no_escape": true
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "span",
+                        "children": [
+                          {
+                            "text": "B"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p id=\"status\"><noscript><strong>A</strong></noscript><span>B</span></p></body></html>",
+        "noQuirksBodyHtml": "<p id=\"status\"><noscript>&lt;strong&gt;A&lt;/strong&gt;</noscript><span>B</span></p>"
+      }
+    },
+    {
+      "data": "<p id=\"status\"><noscript><strong>A</strong></noscript><span>B</span></p>",
+      "errors": [
+        "(1,15): expected-doctype-but-got-start-tag"
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "noscript": true,
+            "strong": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "attrs": [
+                      {
+                        "name": "id",
+                        "value": "status"
+                      }
+                    ],
+                    "children": [
+                      {
+                        "tag": "noscript",
+                        "children": [
+                          {
+                            "tag": "strong",
+                            "children": [
+                              {
+                                "text": "A"
+                              }
+                            ]
+                          }
+                        ]
+                      },
+                      {
+                        "tag": "span",
+                        "children": [
+                          {
+                            "text": "B"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><p id=\"status\"><noscript><strong>A</strong></noscript><span>B</span></p></body></html>",
+        "noQuirksBodyHtml": "<p id=\"status\"><noscript>&lt;strong&gt;A&lt;/strong&gt;</noscript><span>B</span></p>"
+      }
+    },
+    {
+      "data": "<div><sarcasm><div></div></sarcasm></div>",
+      "errors": [
+        "(1,5): expected-doctype-but-got-start-tag"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "div": true,
+            "sarcasm": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "div",
+                    "children": [
+                      {
+                        "tag": "sarcasm",
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><div><sarcasm><div></div></sarcasm></div></body></html>",
+        "noQuirksBodyHtml": "<div><sarcasm><div></div></sarcasm></div>"
+      }
+    },
+    {
+      "data": "<html><body><img src=\"\" border=\"0\" alt=\"><div>A</div></body></html>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,67): eof-in-attribute-value-double-quote"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<table><td></tbody>A",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,20): foster-parenting-character",
+        "(1,20): eof-in-table"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "A"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>A<table><tbody><tr><td></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "A<table><tbody><tr><td></td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><td></thead>A",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,19): XXX-undefined-error",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "A"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td>A</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td>A</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><td></tfoot>A",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,11): unexpected-cell-in-table-body",
+        "(1,19): XXX-undefined-error",
+        "(1,20): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "A"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><tbody><tr><td>A</td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "<table><tbody><tr><td>A</td></tr></tbody></table>"
+      }
+    },
+    {
+      "data": "<table><thead><td></tbody>A",
+      "errors": [
+        "(1,7): expected-doctype-but-got-start-tag",
+        "(1,18): unexpected-cell-in-table-body",
+        "(1,26): XXX-undefined-error",
+        "(1,27): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "thead": true,
+            "tr": true,
+            "td": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "thead",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "text": "A"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><table><thead><tr><td>A</td></tr></thead></table></body></html>",
+        "noQuirksBodyHtml": "<table><thead><tr><td>A</td></tr></thead></table>"
+      }
+    },
+    {
+      "data": "<legend>test</legend>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "legend": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "legend",
+                    "children": [
+                      {
+                        "text": "test"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><legend>test</legend></body></html>",
+        "noQuirksBodyHtml": "<legend>test</legend>"
+      }
+    },
+    {
+      "data": "<table><input>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "input": true,
+            "table": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "input"
+                  },
+                  {
+                    "tag": "table"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><input><table></table></body></html>",
+        "noQuirksBodyHtml": "<input><table></table>"
+      }
+    },
+    {
+      "data": "<b><em><foo><foo><aside></b>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "em": true,
+            "foo": true,
+            "aside": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "em",
+                        "children": [
+                          {
+                            "tag": "foo",
+                            "children": [
+                              {
+                                "tag": "foo"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "em",
+                    "children": [
+                      {
+                        "tag": "aside",
+                        "children": [
+                          {
+                            "tag": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><em><foo><foo></foo></foo></em></b><em><aside><b></b></aside></em></body></html>",
+        "noQuirksBodyHtml": "<b><em><foo><foo></foo></foo></em></b><em><aside><b></b></aside></em>"
+      }
+    },
+    {
+      "data": "<b><em><foo><foo><aside></b></em>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "em": true,
+            "foo": true,
+            "aside": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "em",
+                        "children": [
+                          {
+                            "tag": "foo",
+                            "children": [
+                              {
+                                "tag": "foo"
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "em"
+                  },
+                  {
+                    "tag": "aside",
+                    "children": [
+                      {
+                        "tag": "em",
+                        "children": [
+                          {
+                            "tag": "b"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><em><foo><foo></foo></foo></em></b><em></em><aside><em><b></b></em></aside></body></html>",
+        "noQuirksBodyHtml": "<b><em><foo><foo></foo></foo></em></b><em></em><aside><em><b></b></em></aside>"
+      }
+    },
+    {
+      "data": "<b><em><foo><foo><foo><aside></b>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "em": true,
+            "foo": true,
+            "aside": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "em",
+                        "children": [
+                          {
+                            "tag": "foo",
+                            "children": [
+                              {
+                                "tag": "foo",
+                                "children": [
+                                  {
+                                    "tag": "foo"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "aside",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><em><foo><foo><foo></foo></foo></foo></em></b><aside><b></b></aside></body></html>",
+        "noQuirksBodyHtml": "<b><em><foo><foo><foo></foo></foo></foo></em></b><aside><b></b></aside>"
+      }
+    },
+    {
+      "data": "<b><em><foo><foo><foo><aside></b></em>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "b": true,
+            "em": true,
+            "foo": true,
+            "aside": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "em",
+                        "children": [
+                          {
+                            "tag": "foo",
+                            "children": [
+                              {
+                                "tag": "foo",
+                                "children": [
+                                  {
+                                    "tag": "foo"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "aside",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><b><em><foo><foo><foo></foo></foo></foo></em></b><aside><b></b></aside></body></html>",
+        "noQuirksBodyHtml": "<b><em><foo><foo><foo></foo></foo></foo></em></b><aside><b></b></aside>"
+      }
+    },
+    {
+      "data": "<b><em><foo><foo><foo><foo><foo><foo><foo><foo><foo><foo><aside></b></em>",
+      "errors": [],
+      "fragment": {
+        "name": "div"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "b": true,
+            "em": true,
+            "foo": true,
+            "aside": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "b",
+            "children": [
+              {
+                "tag": "em",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "children": [
+                      {
+                        "tag": "foo",
+                        "children": [
+                          {
+                            "tag": "foo",
+                            "children": [
+                              {
+                                "tag": "foo",
+                                "children": [
+                                  {
+                                    "tag": "foo",
+                                    "children": [
+                                      {
+                                        "tag": "foo",
+                                        "children": [
+                                          {
+                                            "tag": "foo",
+                                            "children": [
+                                              {
+                                                "tag": "foo",
+                                                "children": [
+                                                  {
+                                                    "tag": "foo",
+                                                    "children": [
+                                                      {
+                                                        "tag": "foo"
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "tag": "aside",
+            "children": [
+              {
+                "tag": "b"
+              }
+            ]
+          }
+        ],
+        "html": "<b><em><foo><foo><foo><foo><foo><foo><foo><foo><foo><foo></foo></foo></foo></foo></foo></foo></foo></foo></foo></foo></em></b><aside><b></b></aside>",
+        "noQuirksBodyHtml": "<b><em><foo><foo><foo><foo><foo><foo><foo><foo><foo><foo></foo></foo></foo></foo></foo></foo></foo></foo></foo></foo></em></b><aside><b></b></aside>"
+      }
+    },
+    {
+      "data": "<b><em><foo><foob><foob><foob><foob><fooc><fooc><fooc><fooc><food><aside></b></em>",
+      "errors": [],
+      "fragment": {
+        "name": "div"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "b": true,
+            "em": true,
+            "foo": true,
+            "foob": true,
+            "fooc": true,
+            "food": true,
+            "aside": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "b",
+            "children": [
+              {
+                "tag": "em",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "children": [
+                      {
+                        "tag": "foob",
+                        "children": [
+                          {
+                            "tag": "foob",
+                            "children": [
+                              {
+                                "tag": "foob",
+                                "children": [
+                                  {
+                                    "tag": "foob",
+                                    "children": [
+                                      {
+                                        "tag": "fooc",
+                                        "children": [
+                                          {
+                                            "tag": "fooc",
+                                            "children": [
+                                              {
+                                                "tag": "fooc",
+                                                "children": [
+                                                  {
+                                                    "tag": "fooc",
+                                                    "children": [
+                                                      {
+                                                        "tag": "food"
+                                                      }
+                                                    ]
+                                                  }
+                                                ]
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "tag": "aside",
+            "children": [
+              {
+                "tag": "b"
+              }
+            ]
+          }
+        ],
+        "html": "<b><em><foo><foob><foob><foob><foob><fooc><fooc><fooc><fooc><food></food></fooc></fooc></fooc></fooc></foob></foob></foob></foob></foo></em></b><aside><b></b></aside>",
+        "noQuirksBodyHtml": "<b><em><foo><foob><foob><foob><foob><fooc><fooc><fooc><fooc><food></food></fooc></fooc></fooc></fooc></foob></foob></foob></foob></foo></em></b><aside><b></b></aside>"
+      }
+    },
+    {
+      "data": "<isindex action=\"x\">",
+      "errors": [],
+      "fragment": {
+        "name": "table"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "form": true,
+            "hr": true,
+            "label": true,
+            "input": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "form",
+            "attrs": [
+              {
+                "name": "action",
+                "value": "x"
+              }
+            ],
+            "children": [
+              {
+                "tag": "hr"
+              },
+              {
+                "tag": "label",
+                "children": [
+                  {
+                    "text": "This is a searchable index. Enter search keywords: "
+                  },
+                  {
+                    "tag": "input",
+                    "attrs": [
+                      {
+                        "name": "name",
+                        "value": "isindex"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "hr"
+              }
+            ]
+          }
+        ],
+        "html": "<form action=\"x\"><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>",
+        "noQuirksBodyHtml": "<form action=\"x\"><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>"
+      }
+    },
+    {
+      "data": "<option><XH<optgroup></optgroup>",
+      "errors": [],
+      "fragment": {
+        "name": "select"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "option": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "option"
+          }
+        ],
+        "html": "<option></option>",
+        "noQuirksBodyHtml": "<option><xh<optgroup></xh<optgroup></option>"
+      }
+    },
+    {
+      "data": "<svg><foreignObject><div>foo</div><plaintext></foreignObject></svg><div>bar</div>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "div": true,
+            "plaintext": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "div",
+                            "children": [
+                              {
+                                "text": "foo"
+                              }
+                            ]
+                          },
+                          {
+                            "tag": "plaintext",
+                            "children": [
+                              {
+                                "text": "</foreignObject></svg><div>bar</div>",
+                                "no_escape": true
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><foreignObject><div>foo</div><plaintext></foreignObject></svg><div>bar</div></plaintext></foreignObject></svg></body></html>",
+        "noQuirksBodyHtml": "<svg><foreignObject><div>foo</div><plaintext></foreignObject></svg><div>bar</div></plaintext></foreignObject></svg>"
+      }
+    },
+    {
+      "data": "<svg><foreignObject></foreignObject><title></svg>foo",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg foreignObject": true,
+            "svg title": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "foreignObject",
+                        "ns": "http://www.w3.org/2000/svg"
+                      },
+                      {
+                        "tag": "title",
+                        "ns": "http://www.w3.org/2000/svg"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "foo"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><svg><foreignObject></foreignObject><title></title></svg>foo</body></html>",
+        "noQuirksBodyHtml": "<svg><foreignObject></foreignObject><title></title></svg>foo"
+      }
+    },
+    {
+      "data": "</foreignObject><plaintext><div>foo</div>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "plaintext": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "plaintext",
+                    "children": [
+                      {
+                        "text": "<div>foo</div>",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><plaintext><div>foo</div></plaintext></body></html>",
+        "noQuirksBodyHtml": "<plaintext><div>foo</div></plaintext>"
+      }
+    }
+  ]
+}
index 4d914e4..e7ac940 100644 (file)
@@ -355,9 +355,9 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                        // XML/HTML character entity references
                        // Note: Commented out because they are not marked invalid by the PHP test as
                        // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first.
-                       // array( 'A &eacute; B' ),
-                       // array( 'A &#233; B' ),
-                       // array( 'A &#x00E9; B' ),
+                       // [ 'A &eacute; B' ],
+                       // [ 'A &#233; B' ],
+                       // [ 'A &#x00E9; B' ],
                        // Subject of NS_TALK does not roundtrip to NS_MAIN
                        [ 'Talk:File:Example.svg' ],
                        // Directory navigation
index d04e0fc..1369406 100644 (file)
@@ -837,30 +837,60 @@ class DjVuSupport {
  * Initialize and detect the tidy support
  */
 class TidySupport {
-       private $internalTidy;
-       private $externalTidy;
+       private $enabled;
+       private $config;
 
        /**
         * Determine if there is a usable tidy.
         */
-       public function __construct() {
-               global $wgTidyBin;
-
-               $this->internalTidy = extension_loaded( 'tidy' ) &&
-                       class_exists( 'tidy' ) && !wfIsHHVM();
-
-               $this->externalTidy = is_executable( $wgTidyBin ) ||
-                       Installer::locateExecutableInDefaultPaths( [ $wgTidyBin ] )
-                       !== false;
-       }
-
-       /**
-        * Returns true if we should use internal tidy.
-        *
-        * @return bool
-        */
-       public function isInternal() {
-               return $this->internalTidy;
+       public function __construct( $useConfiguration = false ) {
+               global $IP, $wgUseTidy, $wgTidyBin, $wgTidyInternal, $wgTidyConfig,
+                       $wgTidyConf, $wgTidyOpts;
+
+               $this->enabled = true;
+               if ( $useConfiguration ) {
+                       if ( $wgTidyConfig !== null ) {
+                               $this->config = $wgTidyConfig;
+                       } elseif ( $wgUseTidy ) {
+                               $this->config = [
+                                       'tidyConfigFile' => $wgTidyConf,
+                                       'debugComment' => false,
+                                       'tidyBin' => $wgTidyBin,
+                                       'tidyCommandLine' => $wgTidyOpts
+                               ];
+                               if ( $wgTidyInternal ) {
+                                       $this->config['driver'] = wfIsHHVM() ? 'RaggettInternalHHVM' : 'RaggettInternalPHP';
+                               } else {
+                                       $this->config['driver'] = 'RaggettExternal';
+                               }
+                       } else {
+                               $this->enabled = false;
+                       }
+               } else {
+                       $this->config = [
+                               'tidyConfigFile' => "$IP/includes/tidy/tidy.conf",
+                               'tidyCommandLine' => '',
+                       ];
+                       if ( extension_loaded( 'tidy' ) && class_exists( 'tidy' ) ) {
+                               $this->config['driver'] = wfIsHHVM() ? 'RaggettInternalHHVM' : 'RaggettInternalPHP';
+                       } else {
+                               if ( is_executable( $wgTidyBin ) ) {
+                                       $this->config['driver'] = 'RaggettExternal';
+                                       $this->config['tidyBin'] = $wgTidyBin;
+                               } else {
+                                       $path = Installer::locateExecutableInDefaultPaths( $wgTidyBin );
+                                       if ( $path !== false ) {
+                                               $this->config['driver'] = 'RaggettExternal';
+                                               $this->config['tidyBin'] = $wgTidyBin;
+                                       } else {
+                                               $this->enabled = false;
+                                       }
+                               }
+                       }
+               }
+               if ( !$this->enabled ) {
+                       $this->config = [ 'driver' => 'disabled' ];
+               }
        }
 
        /**
@@ -869,6 +899,10 @@ class TidySupport {
         * @return bool
         */
        public function isEnabled() {
-               return $this->internalTidy || $this->externalTidy;
+               return $this->enabled;
+       }
+
+       public function getConfig() {
+               return $this->config;
        }
 }