runTests(escapeshellarg(\PHP_BINARY), "typical", $args); } /** Runs the full test suite * * This includes pedantic tests which may help to identify problems. * See help for the "test" task for more details. */ public function testFull(array $args): Result { return $this->runTests(escapeshellarg(\PHP_BINARY), "full", $args); } /** * Runs a quick subset of the test suite * * See help for the "test" task for more details. */ public function testQuick(array $args): Result { return $this->runTests(escapeshellarg(\PHP_BINARY), "quick", $args); } /** Produces a code coverage report * * By default this task produces an HTML-format coverage report in * tests/coverage/. Additional reports may be produced by passing * arguments to this task as one would to PHPUnit. * * Robo first tries to use pcov and will fall back to xdebug. * Neither pcov nor xdebug need to be enabled to be used; they * only need to be present in the extension load path to be used. */ public function coverage(array $args): Result { // run tests with code coverage reporting enabled $exec = $this->findCoverageEngine(); return $this->runTests($exec, "coverage", array_merge(["--coverage-html", BASE_TEST."coverage"], $args)); } /** Produces a code coverage report, with redundant tests * * Depending on the environment, some tests that normally provide * coverage may be skipped, while working alternatives are normally * suppressed for reasons of time. This coverage report will try to * run all tests which may cover code. * * See also help for the "coverage" task for more details. */ public function coverageFull(array $args): Result { // run tests with code coverage reporting enabled $exec = $this->findCoverageEngine(); return $this->runTests($exec, "typical", array_merge(["--coverage-html", BASE_TEST."coverage"], $args)); } /** Finds the first suitable means of computing code coverage, either pcov or xdebug. */ protected function findCoverageEngine(): string { $dir = rtrim(ini_get("extension_dir"), "/").\DIRECTORY_SEPARATOR; $ext = IS_WIN ? "dll" : "so"; $php = escapeshellarg(\PHP_BINARY); $code = escapeshellarg(BASE."lib"); if (extension_loaded("pcov")) { return "$php -d pcov.enabled=1 -d pcov.directory=$code"; } elseif (extension_loaded("xdebug")) { return "$php -d xdebug.mode=coverage"; } elseif (file_exists($dir."pcov.$ext")) { return "$php -d extension=pcov.$ext -d pcov.enabled=1 -d pcov.directory=$code"; } elseif (file_exists($dir."xdebug.$ext")) { return "$php -d zend_extension=xdebug.$ext -d xdebug.mode=coverage"; } else { return $php; } } /** Returns the necessary shell arguments to print error output or all output to the bitbucket * * @param bool $all Whether all output (true) or only error output (false) should be suppressed */ protected function blackhole(bool $all = false): string { $hole = IS_WIN ? "nul" : "/dev/null"; return $all ? ">$hole 2>&1" : "2>$hole"; } /** Executes PHPUnit, used by the test and coverage tasks. * * @param string $executor The path to the PHP binary to execute with any required extra arguments. Normally this is either "php" or the result of findCoverageEngine() * @param string $set The set of tests to run, either "typical" (excludes redundant tests), "quick" (excludes redundant and slow tests), "coverage" (excludes tests not needed for coverage), or "full" (all tests) * @param array $args Extra arguments passed by Robo from the command line */ protected function runTests(string $executor, string $set, array $args): Result { switch ($set) { case "typical": $set = ["--exclude-group", "optional"]; break; case "quick": $set = ["--exclude-group", "optional,slow"]; break; case "coverage": $set = ["--exclude-group", "optional,coverageOptional"]; break; case "full": $set = []; break; default: throw new \Exception; } $execpath = norm(BASE."vendor-bin/phpunit/vendor/phpunit/phpunit/phpunit"); $confpath = realpath(BASE_TEST."phpunit.dist.xml") ?: norm(BASE_TEST."phpunit.xml"); return $this->taskExec($executor)->option("-d", "zend.assertions=1")->arg($execpath)->option("-c", $confpath)->args(array_merge($set, $args))->run(); } /** Manually updates the imported web-platform-tests test suite */ public function testUpdate(): Result { $repos = [ 'platform-tests' => "https://github.com/web-platform-tests/wpt", ]; $c = $this->collectionBuilder(); foreach ($repos as $dir => $url) { $dir = BASE_TEST.$dir; if (is_dir($dir)) { $c->addTask($this->taskGitStack()->dir($dir)->pull()); } else { $c->addTask($this->taskGitStack()->cloneRepo($url, $dir)); } } $c->addTask($this->taskExec(BASE_TEST."parsetests")->arg(BASE_TEST."platform-tests")->rawArg(">")->arg(BASE_TEST."cases".DIRECTORY_SEPARATOR."std-sanitize.json")); return $c->run(); } public function constants(): Result { $c = $this->collectionBuilder()->addCode(function() { $elems = [ 'self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"], ]; $attrs = [ 'self::NULL_NAMESPACE' => [ 'accumulate' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform"]], 'additive' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform"]], 'amplitude' => ['self::SVG_NAMESPACE' => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'aria-activedescendant' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-atomic' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-autocomplete' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-busy' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-checked' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-colcount' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-colindex' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-colspan' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-controls' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-current' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-describedby' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-details' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-disabled' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-dropeffect' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-errormessage' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-expanded' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-flowto' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-grabbed' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-haspopup' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-hidden' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-invalid' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-keyshortcuts' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-label' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-labelledby' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-level' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-live' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-modal' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-multiline' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-multiselectable' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-orientation' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-owns' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-placeholder' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-posinset' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-pressed' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-readonly' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-relevant' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-required' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-roledescription' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-rowcount' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-rowindex' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-rowspan' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-selected' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-setsize' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-sort' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-valuemax' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-valuemin' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-valuenow' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-valuetext' => ['self::HTML_NAMESPACE' => ["*"], 'self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'attributeName' => ['self::SVG_NAMESPACE' => ["animate", "animateTransform", "set"]], 'azimuth' => ['self::SVG_NAMESPACE' => ["feDistantLight"]], 'baseFrequency' => ['self::SVG_NAMESPACE' => ["feTurbulence"]], 'begin' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set", "discard"]], 'bias' => ['self::SVG_NAMESPACE' => ["feConvolveMatrix"]], 'by' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform"]], 'calcMode' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform"]], 'class' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'clipPathUnits' => ['self::SVG_NAMESPACE' => ["clipPath"]], 'crossorigin' => ['self::SVG_NAMESPACE' => ["feImage", "image", "script"]], 'cx' => ['self::SVG_NAMESPACE' => ["radialGradient", "circle", "ellipse"]], 'cy' => ['self::SVG_NAMESPACE' => ["radialGradient", "circle", "ellipse"]], 'd' => ['self::SVG_NAMESPACE' => ["path"]], 'diffuseConstant' => ['self::SVG_NAMESPACE' => ["feDiffuseLighting"]], 'divisor' => ['self::SVG_NAMESPACE' => ["feConvolveMatrix"]], 'download' => ['self::SVG_NAMESPACE' => ["a"]], 'dur' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'dx' => ['self::SVG_NAMESPACE' => ["feDropShadow", "feOffset", "text", "tspan"]], 'dy' => ['self::SVG_NAMESPACE' => ["feDropShadow", "feOffset", "text", "tspan"]], 'edgeMode' => ['self::SVG_NAMESPACE' => ["feConvolveMatrix"]], 'edgeMode' => ['self::SVG_NAMESPACE' => ["feGaussianBlur"]], 'elevation' => ['self::SVG_NAMESPACE' => ["feDistantLight"]], 'end' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'exponent' => ['self::SVG_NAMESPACE' => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'fill' => ['self::SVG_NAMESPACE' => ["*"]], 'filterUnits' => ['self::SVG_NAMESPACE' => ["filter"]], 'fr' => ['self::SVG_NAMESPACE' => ["radialGradient"]], 'from' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform"]], 'fx' => ['self::SVG_NAMESPACE' => ["radialGradient"]], 'fy' => ['self::SVG_NAMESPACE' => ["radialGradient"]], 'gradientTransform' => ['self::SVG_NAMESPACE' => ["linearGradient", "radialGradient"]], 'gradientUnits' => ['self::SVG_NAMESPACE' => ["linearGradient", "radialGradient"]], 'height' => ['self::SVG_NAMESPACE' => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "feSpecularLighting", "feTile", "feTurbulence", "filter", "mask", "pattern", "foreignObject", "image", "rect", "svg", "symbol", "use"]], 'href' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "set", "discard", "feImage", "image", "linearGradient", "mpath", "pattern", "radialGradient", "script", "textPath", "use"]], 'hreflang' => ['self::SVG_NAMESPACE' => ["a"]], 'id' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'in' => ['self::SVG_NAMESPACE' => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feGaussianBlur", "feMergeNode", "feMorphology", "feOffset", "feSpecularLighting", "feTile"]], 'in2' => ['self::SVG_NAMESPACE' => ["feBlend", "feComposite", "feDisplacementMap"]], 'intercept' => ['self::SVG_NAMESPACE' => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'k1' => ['self::SVG_NAMESPACE' => ["feComposite"]], 'k2' => ['self::SVG_NAMESPACE' => ["feComposite"]], 'k3' => ['self::SVG_NAMESPACE' => ["feComposite"]], 'k4' => ['self::SVG_NAMESPACE' => ["feComposite"]], 'kernelMatrix' => ['self::SVG_NAMESPACE' => ["feConvolveMatrix", "feConvolveMatrix", "feDiffuseLighting", "feSpecularLighting"]], 'keyPoints' => ['self::SVG_NAMESPACE' => ["animateMotion"]], 'keySplines' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform"]], 'keyTimes' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform"]], 'lang' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'lengthAdjust' => ['self::SVG_NAMESPACE' => ["text", "textPath", "tspan"]], 'limitingConeAngle' => ['self::SVG_NAMESPACE' => ["feSpotLight"]], 'markerHeight' => ['self::SVG_NAMESPACE' => ["marker"]], 'markerUnits' => ['self::SVG_NAMESPACE' => ["marker"]], 'markerWidth' => ['self::SVG_NAMESPACE' => ["marker"]], 'maskContentUnits' => ['self::SVG_NAMESPACE' => ["mask"]], 'maskUnits' => ['self::SVG_NAMESPACE' => ["mask"]], 'max' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'media' => ['self::SVG_NAMESPACE' => ["style"]], 'method' => ['self::SVG_NAMESPACE' => ["textPath"]], 'min' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'mode' => ['self::SVG_NAMESPACE' => ["feBlend"]], 'numOctaves' => ['self::SVG_NAMESPACE' => ["feTurbulence"]], 'offset' => ['self::SVG_NAMESPACE' => ["feFuncA", "feFuncB", "feFuncG", "feFuncR", "stop"]], 'onabort' => ['self::SVG_NAMESPACE' => ["svg"]], 'onafterprint' => ['self::SVG_NAMESPACE' => ["*"]], 'onbeforeprint' => ['self::SVG_NAMESPACE' => ["*"]], 'onbegin' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'oncancel' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncanplay' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncanplaythrough' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onchange' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onclick' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onclose' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncopy' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncuechange' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncut' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondblclick' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondrag' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragend' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragenter' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragexit' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragleave' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragover' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragstart' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondrop' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondurationchange' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onemptied' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onend' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'onended' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onerror' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view", "svg"]], 'onfocus' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onfocusin' => ['self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "defs", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video"]], 'onfocusout' => ['self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "defs", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video"]], 'onhashchange' => ['self::SVG_NAMESPACE' => ["*"]], 'oninput' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oninvalid' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onkeydown' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onkeypress' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onkeyup' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onload' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onloadeddata' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onloadedmetadata' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onloadstart' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmessage' => ['self::SVG_NAMESPACE' => ["*"]], 'onmousedown' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseenter' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseleave' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmousemove' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseout' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseover' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseup' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmousewheel' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onoffline' => ['self::SVG_NAMESPACE' => ["*"]], 'ononline' => ['self::SVG_NAMESPACE' => ["*"]], 'onpagehide' => ['self::SVG_NAMESPACE' => ["*"]], 'onpageshow' => ['self::SVG_NAMESPACE' => ["*"]], 'onpaste' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onpause' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onplay' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onplaying' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onpopstate' => ['self::SVG_NAMESPACE' => ["*"]], 'onprogress' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onratechange' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onrepeat' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'onreset' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onresize' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view", "svg"]], 'onscroll' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view", "svg"]], 'onseeked' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onseeking' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onselect' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onshow' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onstalled' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onstorage' => ['self::SVG_NAMESPACE' => ["*"]], 'onsubmit' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onsuspend' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ontimeupdate' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ontoggle' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onunload' => ['self::SVG_NAMESPACE' => ["*"]], 'onvolumechange' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onwaiting' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'operator' => ['self::SVG_NAMESPACE' => ["feComposite", "feMorphology"]], 'order' => ['self::SVG_NAMESPACE' => ["feConvolveMatrix"]], 'orient' => ['self::SVG_NAMESPACE' => ["marker"]], 'origin' => ['self::SVG_NAMESPACE' => ["animateMotion"]], 'path' => ['self::SVG_NAMESPACE' => ["animateMotion", "textPath"]], 'pathLength' => ['self::SVG_NAMESPACE' => ["circle", "ellipse", "line", "path", "polygon", "polyline", "rect"]], 'patternContentUnits' => ['self::SVG_NAMESPACE' => ["pattern"]], 'patternTransform' => ['self::SVG_NAMESPACE' => ["pattern"]], 'patternUnits' => ['self::SVG_NAMESPACE' => ["pattern"]], 'ping' => ['self::SVG_NAMESPACE' => ["a"]], 'playbackorder' => ['self::SVG_NAMESPACE' => ["svg"]], 'points' => ['self::SVG_NAMESPACE' => ["polygon", "polyline"]], 'pointsAtX' => ['self::SVG_NAMESPACE' => ["feSpotLight"]], 'pointsAtY' => ['self::SVG_NAMESPACE' => ["feSpotLight"]], 'pointsAtZ' => ['self::SVG_NAMESPACE' => ["feSpotLight"]], 'preserveAlpha' => ['self::SVG_NAMESPACE' => ["feConvolveMatrix"]], 'preserveAspectRatio' => ['self::SVG_NAMESPACE' => ["canvas", "feImage", "image", "marker", "pattern", "svg", "symbol", "view"]], 'primitiveUnits' => ['self::SVG_NAMESPACE' => ["filter"]], 'r' => ['self::SVG_NAMESPACE' => ["radialGradient", "circle"]], 'radius' => ['self::SVG_NAMESPACE' => ["feMorphology"]], 'refX' => ['self::SVG_NAMESPACE' => ["marker", "symbol"]], 'refY' => ['self::SVG_NAMESPACE' => ["marker", "symbol"]], 'referrerpolicy' => ['self::SVG_NAMESPACE' => ["a"]], 'rel' => ['self::SVG_NAMESPACE' => ["a"]], 'repeatCount' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'repeatDur' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'requiredExtensions' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "mask", "path", "polygon", "polyline", "rect", "set", "svg", "switch", "text", "textPath", "tspan", "unknown", "use", "video"]], 'restart' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'result' => ['self::SVG_NAMESPACE' => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "feSpecularLighting", "feTile", "feTurbulence"]], 'role' => ['self::SVG_NAMESPACE' => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'rotate' => ['self::SVG_NAMESPACE' => ["animateMotion", "text", "tspan"]], 'rx' => ['self::SVG_NAMESPACE' => ["ellipse", "rect"]], 'ry' => ['self::SVG_NAMESPACE' => ["ellipse", "rect"]], 'scale' => ['self::SVG_NAMESPACE' => ["feDisplacementMap"]], 'seed' => ['self::SVG_NAMESPACE' => ["feTurbulence"]], 'side' => ['self::SVG_NAMESPACE' => ["textPath"]], 'slope' => ['self::SVG_NAMESPACE' => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'spacing' => ['self::SVG_NAMESPACE' => ["textPath"]], 'specularConstant' => ['self::SVG_NAMESPACE' => ["feSpecularLighting"]], 'specularExponent' => ['self::SVG_NAMESPACE' => ["feSpecularLighting", "feSpotLight"]], 'spreadMethod' => ['self::SVG_NAMESPACE' => ["linearGradient", "radialGradient"]], 'startOffset' => ['self::SVG_NAMESPACE' => ["textPath"]], 'stdDeviation' => ['self::SVG_NAMESPACE' => ["feDropShadow", "feGaussianBlur"]], 'stitchTiles' => ['self::SVG_NAMESPACE' => ["feTurbulence"]], 'style' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'surfaceScale' => ['self::SVG_NAMESPACE' => ["feDiffuseLighting", "feSpecularLighting"]], 'systemLanguage' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "mask", "path", "polygon", "polyline", "rect", "set", "svg", "switch", "text", "textPath", "tspan", "unknown", "use", "video"]], 'tabindex' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'tableValues' => ['self::SVG_NAMESPACE' => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'target' => ['self::SVG_NAMESPACE' => ["a"]], 'targetX' => ['self::SVG_NAMESPACE' => ["feConvolveMatrix"]], 'targetY' => ['self::SVG_NAMESPACE' => ["feConvolveMatrix"]], 'textLength' => ['self::SVG_NAMESPACE' => ["text", "textPath", "tspan"]], 'timelinebegin' => ['self::SVG_NAMESPACE' => ["svg"]], 'title' => ['self::SVG_NAMESPACE' => ["style"]], 'to' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "set"]], 'transform' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "g", "iframe", "image", "line", "marker", "mask", "metadata", "mpath", "path", "polygon", "polyline", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'type' => ['self::SVG_NAMESPACE' => ["a", "animateTransform", "feColorMatrix", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feTurbulence", "script", "style"]], 'values' => ['self::SVG_NAMESPACE' => ["animate", "animateMotion", "animateTransform", "feColorMatrix"]], 'viewBox' => ['self::SVG_NAMESPACE' => ["marker", "pattern", "svg", "symbol", "view"]], 'width' => ['self::SVG_NAMESPACE' => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "feSpecularLighting", "feTile", "feTurbulence", "filter", "mask", "pattern", "foreignObject", "image", "rect", "svg", "symbol", "use"]], 'x' => ['self::SVG_NAMESPACE' => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "feSpecularLighting", "feTile", "feTurbulence", "fePointLight", "feSpotLight", "filter", "mask", "pattern", "text", "tspan", "foreignObject", "image", "rect", "svg", "symbol", "use"]], 'x1' => ['self::SVG_NAMESPACE' => ["line", "linearGradient"]], 'x2' => ['self::SVG_NAMESPACE' => ["line", "linearGradient"]], 'xChannelSelector' => ['self::SVG_NAMESPACE' => ["feDisplacementMap"]], 'y' => ['self::SVG_NAMESPACE' => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "feSpecularLighting", "feTile", "feTurbulence", "fePointLight", "feSpotLight", "filter", "mask", "pattern", "text", "tspan", "foreignObject", "image", "rect", "svg", "symbol", "use"]], 'y1' => ['self::SVG_NAMESPACE' => ["line", "linearGradient"]], 'y2' => ['self::SVG_NAMESPACE' => ["line", "linearGradient"]], 'yChannelSelector' => ['self::SVG_NAMESPACE' => ["feDisplacementMap"]], 'z' => ['self::SVG_NAMESPACE' => ["fePointLight", "feSpotLight"]], 'zoomAndPan' => ['self::SVG_NAMESPACE' => ["svg", "view"]], 'alignment-baseline' => ['self::SVG_NAMESPACE' => ["*"]], 'baseline-shift' => ['self::SVG_NAMESPACE' => ["*"]], 'clip-path' => ['self::SVG_NAMESPACE' => ["*"]], 'clip-rule' => ['self::SVG_NAMESPACE' => ["*"]], 'color' => ['self::SVG_NAMESPACE' => ["*"]], 'color-interpolation' => ['self::SVG_NAMESPACE' => ["*"]], 'color-interpolation-filters' => ['self::SVG_NAMESPACE' => ["*"]], 'color-rendering' => ['self::SVG_NAMESPACE' => ["*"]], 'cursor' => ['self::SVG_NAMESPACE' => ["*"]], 'direction' => ['self::SVG_NAMESPACE' => ["*"]], 'display' => ['self::SVG_NAMESPACE' => ["*"]], 'dominant-baseline' => ['self::SVG_NAMESPACE' => ["*"]], 'fill-opacity' => ['self::SVG_NAMESPACE' => ["*"]], 'fill-rule' => ['self::SVG_NAMESPACE' => ["*"]], 'filter' => ['self::SVG_NAMESPACE' => ["*"]], 'flood-color' => ['self::SVG_NAMESPACE' => ["*"]], 'flood-opacity' => ['self::SVG_NAMESPACE' => ["*"]], 'font-family' => ['self::SVG_NAMESPACE' => ["*"]], 'font-size' => ['self::SVG_NAMESPACE' => ["*"]], 'font-size-adjust' => ['self::SVG_NAMESPACE' => ["*"]], 'font-stretch' => ['self::SVG_NAMESPACE' => ["*"]], 'font-style' => ['self::SVG_NAMESPACE' => ["*"]], 'font-variant' => ['self::SVG_NAMESPACE' => ["*"]], 'font-weight' => ['self::SVG_NAMESPACE' => ["*"]], 'glyph-orientation-horizontal' => ['self::SVG_NAMESPACE' => ["*"]], 'glyph-orientation-vertical' => ['self::SVG_NAMESPACE' => ["*"]], 'image-rendering' => ['self::SVG_NAMESPACE' => ["*"]], 'letter-spacing' => ['self::SVG_NAMESPACE' => ["*"]], 'lighting-color' => ['self::SVG_NAMESPACE' => ["*"]], 'marker-end' => ['self::SVG_NAMESPACE' => ["*"]], 'marker-mid' => ['self::SVG_NAMESPACE' => ["*"]], 'marker-start' => ['self::SVG_NAMESPACE' => ["*"]], 'mask' => ['self::SVG_NAMESPACE' => ["*"]], 'opacity' => ['self::SVG_NAMESPACE' => ["*"]], 'overflow' => ['self::SVG_NAMESPACE' => ["*"]], 'paint-order' => ['self::SVG_NAMESPACE' => ["*"]], 'pointer-events' => ['self::SVG_NAMESPACE' => ["*"]], 'shape-rendering' => ['self::SVG_NAMESPACE' => ["*"]], 'stop-color' => ['self::SVG_NAMESPACE' => ["*"]], 'stop-opacity' => ['self::SVG_NAMESPACE' => ["*"]], 'stroke' => ['self::SVG_NAMESPACE' => ["*"]], 'stroke-dasharray' => ['self::SVG_NAMESPACE' => ["*"]], 'stroke-dashoffset' => ['self::SVG_NAMESPACE' => ["*"]], 'stroke-linecap' => ['self::SVG_NAMESPACE' => ["*"]], 'stroke-linejoin' => ['self::SVG_NAMESPACE' => ["*"]], 'stroke-miterlimit' => ['self::SVG_NAMESPACE' => ["*"]], 'stroke-opacity' => ['self::SVG_NAMESPACE' => ["*"]], 'stroke-width' => ['self::SVG_NAMESPACE' => ["*"]], 'text-anchor' => ['self::SVG_NAMESPACE' => ["*"]], 'text-decoration' => ['self::SVG_NAMESPACE' => ["*"]], 'text-overflow' => ['self::SVG_NAMESPACE' => ["*"]], 'text-rendering' => ['self::SVG_NAMESPACE' => ["*"]], 'unicode-bidi' => ['self::SVG_NAMESPACE' => ["*"]], 'vector-effect' => ['self::SVG_NAMESPACE' => ["*"]], 'visibility' => ['self::SVG_NAMESPACE' => ["*"]], 'white-space' => ['self::SVG_NAMESPACE' => ["*"]], 'word-spacing' => ['self::SVG_NAMESPACE' => ["*"]], 'writing-mode' => ['self::SVG_NAMESPACE' => ["*"]], ], 'self::XLINK_NAMESPACE' => [ 'href' => ['self::SVG_NAMESPACE' => ["a", "image", "linearGradient", "pattern", "radialGradient", "script", "textPath", "use", "feImage"]], 'title' => ['self::SVG_NAMESPACE' => ["a", "image", "linearGradient", "pattern", "radialGradient", "script", "textPath", "use"]], ], 'self::XML_NAMESPACE' => [ 'space' => ['self::SVG_NAMESPACE' => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], ], ]; // retrieve the single-page HTML specification (this is around 12MB in size) $spec = file_get_contents("https://html.spec.whatwg.org/"); // parse it (this may take several seconds if ($spec) { // define a list of attribute-element maps which the specification omits for some reason $extra = [ 'background' => ["body", "table", "thead", "tbody", "tfoot", "tr", "td", "th"], 'contextmenu' => ["*"], 'datafld' => ["a", "button", "div", "fieldset", "frame", "iframe", "img", "input", "label", "legend", "marquee", "object", "select", "span", "textarea"], 'dataformatas' => ["button", "div", "input", "label", "legend", "marquee", "object", "option", "select", "span", "table"], 'datasrc' => ["a", "button", "div", "frame", "iframe", "img", "input", "label", "legend", "marquee", "object", "option", "select", "span", "table", "textarea"], 'dropzone' => ["*"], 'role' => ["*"], ]; $p = new DOMParser; $document = $p->parseFromString($spec, "text/html;charset=utf-8"); // pick out element and attribute definitions from the specification $elems["self::HTML_NAMESPACE"] = []; foreach ($document->getElementsByTagName("dfn") as $el) { $type = $el->getAttribute("data-dfn-type"); if ($type === "element") { $elems["self::HTML_NAMESPACE"][] = trim($el->textContent); } elseif ($type === "element-attr") { $name = trim($el->textContent); if (preg_match('/\s/', $name)) { // skip the definition if the name is not valid continue; } $attrs['self::NULL_NAMESPACE'][$name] = $attrs['self::NULL_NAMESPACE'][$name] ?? []; $attrs['self::NULL_NAMESPACE'][$name]['self::HTML_NAMESPACE'] = $attrs['self::NULL_NAMESPACE'][$name]['self::HTML_NAMESPACE'] ?? []; $context = $el->getAttribute("data-dfn-for") ?? ""; if (strlen($context)) { $context = explode(",", $context); $attrs['self::NULL_NAMESPACE'][$name]['self::HTML_NAMESPACE'] = array_merge($attrs['self::NULL_NAMESPACE'][$name]['self::HTML_NAMESPACE'], $context); } elseif (isset($extra[$name])) { $attrs['self::NULL_NAMESPACE'][$name]['self::HTML_NAMESPACE'] = array_merge($attrs['self::NULL_NAMESPACE'][$name]['self::HTML_NAMESPACE'], $extra[$name]); } else { throw new \Exception("Attribute $name oes not have an element list defined; check the HTML specification"); } } elseif ($type === "attribute") { $name = trim(trim($el->textContent), "*"); $context = $el->getAttribute("data-dfn-for"); if (preg_match('/^platform object$|^[A-Z]/', $context)) { // this is either a slot or an IDL attribute continue; } $attrs['self::NULL_NAMESPACE'][$name] = $attrs['self::NULL_NAMESPACE'][$name] ?? []; $attrs['self::NULL_NAMESPACE'][$name]['self::HTML_NAMESPACE'] = ["*"]; } } // do a second pass over attributes which have been collected to find globals and normalize them to a single "*" entry $attrs['self::NULL_NAMESPACE'] = array_map(function($v) { if (!isset($v['self::HTML_NAMESPACE'])) { return $v; } elseif (array_intersect($v['self::HTML_NAMESPACE'], ["global", "html-global", "htmlsvg-global"])) { return ['self::HTML_NAMESPACE' => ["*"]]; } else { return $v; } }, $attrs['self::NULL_NAMESPACE']); // sort the elements sort($elems['self::HTML_NAMESPACE']); $elems['self::HTML_NAMESPACE'] = array_unique($elems['self::HTML_NAMESPACE']); } // sort and filter the results for unqiueness ksort($attrs['self::NULL_NAMESPACE']); $attrs['self::NULL_NAMESPACE'] = array_map(function($v) { foreach ($v as $k => $vv) { sort($v[$k]); } return $v; }, $attrs['self::NULL_NAMESPACE']); // formt the lists as a PHP arrays foreach (['elems' => $elems, 'attrs' => $attrs] as $k => $v) { $v = json_encode($v); $v = str_replace(["{", "}", ","], ["[", "]", ", "], $v); $v = preg_replace('/"([^"]+)":/', "'$1' => ", $v); $v = preg_replace("/'(self::[A-Z]+_NAMESPACE)'/", "$1", $v); $$k = $v; } // output the result echo "protected const KNOWN_ELEMENTS = ".$elems.";\n"; echo "protected const KNOWN_ATTRIBUTES = ".$attrs.";\n"; }); return $c->run(); } }